使用 XmlReader 获取节点的 XPath
Getting XPath for node with XmlReader
如何使用 XMLReader
获取当前节点的 XPath?
例如:
<Employee>
<Entity>
<Id>1</Id>
</Entity>
</Employee>
所以我需要获取 1
的 XPath,即 Employee/Entity/Id
。有什么想法吗?
using (var reader = XmlReader.Create(basePath, settings))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Text)
{
// need to get xpath of the text node
}
else if (reader.NodeType == XmlNodeType.Element)
{
// need to get xpath of the current node
}
}
}
我的第一个建议是使用更高级别 API,例如 LINQ to XML。使用像 XmlReader
这样的低级别 API 的唯一原因是用于非常大的文件。使用 LINQ to XML,一个简单的实现是相当简单的:
var doc = XDocument.Parse(xml);
foreach (var element in doc.Descendants())
{
var path = element.AncestorsAndSelf().Select(e => e.Name.LocalName).Reverse();
var xPath = string.Join("/", path);
}
使用 XmlReader
有点复杂,因为您必须边走边跟踪元素路径:
using (var reader = XmlReader.Create(basePath, settings))
{
var elements = new Stack<string>();
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if(!reader.IsEmptyElement)
elements.Push(reader.LocalName);
break;
case XmlNodeType.EndElement:
elements.Pop();
break;
case XmlNodeType.Text:
path = string.Join("/", elements.Reverse());
break;
}
}
}
这是一个工作演示:https://dotnetfiddle.net/dpOzuL
请注意,虽然这适用于您的简单示例,但这是 XPath
表达式的非常幼稚的创建,并不适用于所有情况(例如,当您有多个同名兄弟姐妹时或者当涉及命名空间时)。
如何使用 XMLReader
获取当前节点的 XPath?
例如:
<Employee>
<Entity>
<Id>1</Id>
</Entity>
</Employee>
所以我需要获取 1
的 XPath,即 Employee/Entity/Id
。有什么想法吗?
using (var reader = XmlReader.Create(basePath, settings))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Text)
{
// need to get xpath of the text node
}
else if (reader.NodeType == XmlNodeType.Element)
{
// need to get xpath of the current node
}
}
}
我的第一个建议是使用更高级别 API,例如 LINQ to XML。使用像 XmlReader
这样的低级别 API 的唯一原因是用于非常大的文件。使用 LINQ to XML,一个简单的实现是相当简单的:
var doc = XDocument.Parse(xml);
foreach (var element in doc.Descendants())
{
var path = element.AncestorsAndSelf().Select(e => e.Name.LocalName).Reverse();
var xPath = string.Join("/", path);
}
使用 XmlReader
有点复杂,因为您必须边走边跟踪元素路径:
using (var reader = XmlReader.Create(basePath, settings))
{
var elements = new Stack<string>();
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if(!reader.IsEmptyElement)
elements.Push(reader.LocalName);
break;
case XmlNodeType.EndElement:
elements.Pop();
break;
case XmlNodeType.Text:
path = string.Join("/", elements.Reverse());
break;
}
}
}
这是一个工作演示:https://dotnetfiddle.net/dpOzuL
请注意,虽然这适用于您的简单示例,但这是 XPath
表达式的非常幼稚的创建,并不适用于所有情况(例如,当您有多个同名兄弟姐妹时或者当涉及命名空间时)。