如何找到特定的xml节点?

时间:2021-01-05 14:01:37

i have this problem to find a particular xml node l have post this problem on * and some nice fellows suggested xpath.

我有这个问题找到一个特定的xml节点我已经在*上发布了这个问题,一些不错的家伙建议xpath。

I am an xml newbie . please I need an c# code to find the parent , parent, parent as (great grand parent) then the first child ,lastchild , lastchild . the code have to iterate up the tree and down again. Be looking at a lot of xpath tutorials online.

我是一个xml新手。请我需要一个c#代码来找到父母,父母,父母(伟大的父母),然后是第一个孩子,最后一个孩子,最后一个孩子。代码必须迭代树并再次向下。在线查看很多xpath教程。

I discovered that the path tend to be specific to a particular node already existing . The program that I need will not get no particular named node because at each pass a new node will be add to the xml tree. The long and short of it all is that I need find the node base on it’s position away from the current node

我发现该路径往往特定于已存在的特定节点。我需要的程序不会得到任何特定的命名节点,因为在每次传递时都会将新节点添加到xml树中。这一切的长短都是我需要找到基于它远离当前节点的位置的节点

i meant finding the parent parent parent of a currentnode (great grand parentnode )then find the first child then find the lastchild lastchild

我的意思是找到currentnode(伟大的父节点)的父父母,然后找到第一个孩子然后找到最后一个子女

keepkind of currentnode.parentnode.parentnode.parentnode.firstchild.lastchild.lastchild;

keepkind of currentnode.parentnode.parentnode.parentnode.firstchild.lastchild.lastchild;

using xpath C#

使用xpath C#

2 个解决方案

#1


Let's say that you have an XmlNode instance called node to start with. Then the following code will give you the last child of the last child of the first child of the great grand parent of that node:

假设您有一个名为node的XmlNode实例。然后,下面的代码将为您提供该节点的祖父的第一个子节点的最后一个子节点的最后一个子节点:

XmlNode wantedNode = node.ParentNode.ParentNode.ParentNode.FirstChild.LastChild.LastChild;

Note that there are so many things that can go wrong with this code. If any of the referenced nodes happen to be null, you have a NullReferenceException coming. So you will want to make a null check at each level:

请注意,此代码可能会出现很多问题。如果任何引用的节点碰巧为null,则会出现NullReferenceException。因此,您需要在每个级别进行空检查:

XmlNode wantedNode;

if (node.ParentNode != null && node.ParentNode.ParentNode != null /* and so on through the full path */)
{
    wantedNode = node.ParentNode.ParentNode.ParentNode.FirstChild.LastChild.LastChild;
}

Let's examine this with a more concrete example. Assume we have the following Xml document:

让我们用一个更具体的例子来研究它。假设我们有以下Xml文档:

<?xml version="1.0" encoding="utf-8" ?>
<root>
  <greatgrandparent>
    <grandparent>
      <parent id="1">
        <child somevalue="3"></child>
      </parent>
      <parent id="2">
        <child somevalue="4"></child>
        <child somevalue="5"></child>
      </parent>
    </grandparent>
  </greatgrandparent>
</root>

If I understand your question right, if we start from the node <child somevalue="3"></child> we want to navigate to <child somevalue="5"></child>. The code sample above will do that. However, as mentioned, it is prone to giving exceptions if not all expected nodes are present.

如果我理解你的问题,如果我们从节点 开始,我们想要导航到 。上面的代码示例将执行此操作。但是,如上所述,如果并非所有预期节点都存在,则很容易给出异常。

Even though you said that you want c# code rather than XPath, in this case I feel that XPath is the way to go. There are a number of ways to solve this. For instance, if the nodes have different tag names (as in my sample document), you can instead do like this:

即使你说你想要c#代码而不是XPath,在这种情况下我觉得XPath是要走的路。有很多方法可以解决这个问题。例如,如果节点具有不同的标记名称(如我的示例文档中所示),您可以这样做:

XmlNode wantedNode = node.SelectSingleNode("ancestor::greatgrandparent/grandparent[position()=1]/parent[position()=last()]/child[position()=last()]");
if (wantedNode != null)
{
    // the path was found
}

This is of course assuming that node is not null, but a valid XmlNode instance.

这当然假设节点不是null,而是一个有效的XmlNode实例。

Breakdown of the XPath expression:

XPath表达式的细分:

  • ancestor::greatgrandparent -> this will locate any node named "greatgrandparent" that is located anywhere upwards in the hierarchy (so any parent, grand parent and so on)
  • ancestor :: greatgrandparent - >这将找到位于层次结构中任何位置的任何名为“greatgrandparent”的节点(因此任何父级,祖父级等等)

  • /grandparent[position()=1] -> the first child node named "grandparent"
  • / grandparent [position()= 1] - >名为“祖父母”的第一个子节点

  • /parent[position()=last()] -> the last child node named "parent"
  • / parent [position()= last()] - >名为“parent”的最后一个子节点

  • /child[position()=last()] -> the last child node named "child"
  • / child [position()= last()] - >名为“child”的最后一个子节点

If you want to read some about how XPath axes work, there is some information on w3schools.com.

如果您想阅读一些有关XPath轴如何工作的信息,请参阅w3schools.com上的一些信息。

#2


All the question you are asking are answered by the XmlNode class. It has properties called ParentNode, FirstChild and LastChild which each return another XmlNode.

您要问的所有问题都由XmlNode类回答。它具有名为ParentNode,FirstChild和LastChild的属性,每个属性都返回另一个XmlNode。

To do the same thing in XPath you can use the ".." abbreviation to get a nodes parent, and "*[position()=1]" or "*[position()=last()]" to get the first and last child, e.g.:

要在XPath中执行相同的操作,您可以使用“..”缩写来获取节点父节点,并使用“* [position()= 1]”或“* [position()= last()]”来获取第一个节点和最后一个孩子,例如:

XmlNode foundNode = node.SelectSingleNode("../../../*[position()=1]/*[position()=last()]/*[position()=last()]");

(Notes: ".." is an abbreviation of the parent::* axis, and "*" is an abbreviation of the "child::*" axis)

(注意:“..”是parent :: *轴的缩写,“*”是“child :: *”轴的缩写)

#1


Let's say that you have an XmlNode instance called node to start with. Then the following code will give you the last child of the last child of the first child of the great grand parent of that node:

假设您有一个名为node的XmlNode实例。然后,下面的代码将为您提供该节点的祖父的第一个子节点的最后一个子节点的最后一个子节点:

XmlNode wantedNode = node.ParentNode.ParentNode.ParentNode.FirstChild.LastChild.LastChild;

Note that there are so many things that can go wrong with this code. If any of the referenced nodes happen to be null, you have a NullReferenceException coming. So you will want to make a null check at each level:

请注意,此代码可能会出现很多问题。如果任何引用的节点碰巧为null,则会出现NullReferenceException。因此,您需要在每个级别进行空检查:

XmlNode wantedNode;

if (node.ParentNode != null && node.ParentNode.ParentNode != null /* and so on through the full path */)
{
    wantedNode = node.ParentNode.ParentNode.ParentNode.FirstChild.LastChild.LastChild;
}

Let's examine this with a more concrete example. Assume we have the following Xml document:

让我们用一个更具体的例子来研究它。假设我们有以下Xml文档:

<?xml version="1.0" encoding="utf-8" ?>
<root>
  <greatgrandparent>
    <grandparent>
      <parent id="1">
        <child somevalue="3"></child>
      </parent>
      <parent id="2">
        <child somevalue="4"></child>
        <child somevalue="5"></child>
      </parent>
    </grandparent>
  </greatgrandparent>
</root>

If I understand your question right, if we start from the node <child somevalue="3"></child> we want to navigate to <child somevalue="5"></child>. The code sample above will do that. However, as mentioned, it is prone to giving exceptions if not all expected nodes are present.

如果我理解你的问题,如果我们从节点 开始,我们想要导航到 。上面的代码示例将执行此操作。但是,如上所述,如果并非所有预期节点都存在,则很容易给出异常。

Even though you said that you want c# code rather than XPath, in this case I feel that XPath is the way to go. There are a number of ways to solve this. For instance, if the nodes have different tag names (as in my sample document), you can instead do like this:

即使你说你想要c#代码而不是XPath,在这种情况下我觉得XPath是要走的路。有很多方法可以解决这个问题。例如,如果节点具有不同的标记名称(如我的示例文档中所示),您可以这样做:

XmlNode wantedNode = node.SelectSingleNode("ancestor::greatgrandparent/grandparent[position()=1]/parent[position()=last()]/child[position()=last()]");
if (wantedNode != null)
{
    // the path was found
}

This is of course assuming that node is not null, but a valid XmlNode instance.

这当然假设节点不是null,而是一个有效的XmlNode实例。

Breakdown of the XPath expression:

XPath表达式的细分:

  • ancestor::greatgrandparent -> this will locate any node named "greatgrandparent" that is located anywhere upwards in the hierarchy (so any parent, grand parent and so on)
  • ancestor :: greatgrandparent - >这将找到位于层次结构中任何位置的任何名为“greatgrandparent”的节点(因此任何父级,祖父级等等)

  • /grandparent[position()=1] -> the first child node named "grandparent"
  • / grandparent [position()= 1] - >名为“祖父母”的第一个子节点

  • /parent[position()=last()] -> the last child node named "parent"
  • / parent [position()= last()] - >名为“parent”的最后一个子节点

  • /child[position()=last()] -> the last child node named "child"
  • / child [position()= last()] - >名为“child”的最后一个子节点

If you want to read some about how XPath axes work, there is some information on w3schools.com.

如果您想阅读一些有关XPath轴如何工作的信息,请参阅w3schools.com上的一些信息。

#2


All the question you are asking are answered by the XmlNode class. It has properties called ParentNode, FirstChild and LastChild which each return another XmlNode.

您要问的所有问题都由XmlNode类回答。它具有名为ParentNode,FirstChild和LastChild的属性,每个属性都返回另一个XmlNode。

To do the same thing in XPath you can use the ".." abbreviation to get a nodes parent, and "*[position()=1]" or "*[position()=last()]" to get the first and last child, e.g.:

要在XPath中执行相同的操作,您可以使用“..”缩写来获取节点父节点,并使用“* [position()= 1]”或“* [position()= last()]”来获取第一个节点和最后一个孩子,例如:

XmlNode foundNode = node.SelectSingleNode("../../../*[position()=1]/*[position()=last()]/*[position()=last()]");

(Notes: ".." is an abbreviation of the parent::* axis, and "*" is an abbreviation of the "child::*" axis)

(注意:“..”是parent :: *轴的缩写,“*”是“child :: *”轴的缩写)