获取的XPath用的XmlReader节点

问题描述 投票:3回答:1

如何获得的XPath与XMLReader当前节点?

E.g:

<Employee>
    <Entity>
        <Id>1</Id>
    </Entity>
</Employee>

所以,我需要得到的XPath 1这是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
        }
     }
 }
c# xmlreader xmlnode
1个回答
5
投票

我的第一个建议是使用更高级别的API类似的LINQ to XML。使用低级别的API像XmlReader的唯一原因是非常大的文件。随着LINQ到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表达的,并不会在所有情况下工作(例如,当你有多个同名的兄弟姐妹或命名空间时涉及)。

© www.soinside.com 2019 - 2024. All rights reserved.