如何从XmlNode实例获取xpath

56

有人可以提供一些代码,以获取System.Xml.XmlNode实例的xpath吗?

谢谢!


请澄清一下,您的意思是指从根节点到该节点的节点名称列表,用 / 分隔开吗? - Chris Marasti-Georg
没错。就像这样... "root/mycars/toyota/description/paragraph"描述元素中可能有多个段落。但我只想让XPath指向XmlNode实例所指的那一个。 - joe
3
人们不应该只是“要求代码” - 他们应该提供他们至少尝试过的一些代码。 - bgmCoder
14个回答

1

解决您问题的另一种方法可能是通过自定义属性“标记”您稍后想要识别的xml节点:

var id = _currentNode.OwnerDocument.CreateAttribute("some_id");
id.Value = Guid.NewGuid().ToString();
_currentNode.Attributes.Append(id);

你可以将其存储在字典中。例如,您可以稍后使用xpath查询标识节点:
newOrOldDocument.SelectSingleNode(string.Format("//*[contains(@some_id,'{0}')]", id));

我知道这不是直接回答你的问题,但如果你想知道节点的xpath是为了在代码中失去对它的引用后能够“找到”节点,这将有所帮助。
这也可以克服文档添加/移动元素时可能会破坏xpath(或索引,如其他答案中所建议)的问题。

0

最近我也需要做这个。只需要考虑元素即可。以下是我的解决方案:

    private string GetPath(XmlElement el)
    {
        List<string> pathList = new List<string>();
        XmlNode node = el;
        while (node is XmlElement)
        {
            pathList.Add(node.Name);
            node = node.ParentNode;
        }
        pathList.Reverse();
        string[] nodeNames = pathList.ToArray();
        return String.Join("/", nodeNames);
    }

0

这甚至更容易

 ''' <summary>
    ''' Gets the full XPath of a single node.
    ''' </summary>
    ''' <param name="node"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function GetXPath(ByVal node As Xml.XmlNode) As String
        Dim temp As String
        Dim sibling As Xml.XmlNode
        Dim previousSiblings As Integer = 1

        'I dont want to know that it was a generic document
        If node.Name = "#document" Then Return ""

        'Prime it
        sibling = node.PreviousSibling
        'Perculate up getting the count of all of this node's sibling before it.
        While sibling IsNot Nothing
            'Only count if the sibling has the same name as this node
            If sibling.Name = node.Name Then
                previousSiblings += 1
            End If
            sibling = sibling.PreviousSibling
        End While

        'Mark this node's index, if it has one
        ' Also mark the index to 1 or the default if it does have a sibling just no previous.
        temp = node.Name + IIf(previousSiblings > 0 OrElse node.NextSibling IsNot Nothing, "[" + previousSiblings.ToString() + "]", "").ToString()

        If node.ParentNode IsNot Nothing Then
            Return GetXPath(node.ParentNode) + "/" + temp
        End If

        Return temp
    End Function

-1
 public static string GetFullPath(this XmlNode node)
        {
            if (node.ParentNode == null)
            {
                return "";
            }
            else
            {
                return $"{GetFullPath(node.ParentNode)}\\{node.ParentNode.Name}";
            }
        }

索引是什么? - Evgeny Gorbovoy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接