我真正喜欢json.net中JsonReader
的地方是,您总是知道当前JsonReader
位置的路径。例如,我们有这样一个json:
{
"name" :
{
"first": "John",
"last": "Smith"
}
}
如果我们是站着或“约翰”元素,
JsonReader.Path
将是“name.first”有没有办法达到类似的效果?可能使用xpath?例如,我们有这样一个XML:
<root>
<name>
<first>John/<first>
<last>Smith</last>
</name>
</root>
我想在站在“john”上时获得“/root/name/first”,在站在“smith”上时获得“/root/name/last”
最佳答案
似乎没有办法使用标准的.NET功能来实现这一点,所以我提出了自己的类。
internal sealed class XmlReaderWrapperWithPath : IDisposable
{
private const string DefaultPathSeparator = ".";
private readonly Stack<string> _previousNames = new Stack<string>();
private readonly XmlReader _reader;
private readonly bool _ownsReader;
public XmlReaderWrapperWithPath(XmlReader reader, bool ownsReader)
{
if (reader == null)
{
throw new ArgumentNullException("reader");
}
_ownsReader = ownsReader;
_reader = reader;
PathSeparator = DefaultPathSeparator;
}
public bool Read()
{
var lastDepth = Depth;
var lastName = Name;
if (!_reader.Read())
{
return false;
}
if (Depth > lastDepth)
{
_previousNames.Push(lastName);
}
else if (Depth < lastDepth)
{
_previousNames.Pop();
}
return true;
}
public string Name
{
get
{
return _reader.Name;
}
}
public string Value
{
get
{
return _reader.Value;
}
}
private int Depth
{
get
{
return _reader.Depth;
}
}
public string Path
{
get
{
return string.Join(PathSeparator, _previousNames.Reverse());
}
}
public string PathSeparator { get; set; }
#region IDisposable
public void Dispose()
{
if (_ownsReader)
{
_reader.Dispose();
}
}
#endregion
}
注意,这个类不构成xpath(所以属性没有路径),但这已经足够满足我的需要了。希望这能帮助别人。