简体   繁体   English

如何找到特定的xml节点?

[英]How to find a specific xml node?

i have this problem to find a particular xml node l have post this problem on stackoverflow and some nice fellows suggested xpath. 我有这个问题来找到一个特定的xml节点l在stackoverflow上发布了这个问题,一些好伙伴建议使用xpath。

I am an xml newbie . 我是xml新手。 please I need an c# code to find the parent , parent, parent as (great grand parent) then the first child ,lastchild , lastchild . 请我需要一个C#代码来找到父代,父代,父代((大祖父母)),然后是第一个孩子,lastchild,lastchild。 the code have to iterate up the tree and down again. 代码必须反复遍历树。 Be looking at a lot of xpath tutorials online. 在线上有很多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. 我需要的程序不会得到任何特定的命名节点,因为每次通过时,都会将一个新节点添加到xml树中。 The long and short of it all is that I need find the node base on it's position away from the current node 总而言之,我需要根据它远离当前节点的位置找到该节点

i meant finding the parent parent parent of a currentnode (great grand parentnode )then find the first child then find the lastchild lastchild 我的意思是找到当前节点的父级父级父节点(伟大的Grand parentnode),然后找到第一个孩子,然后找到最后一个孩子lastchild

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

using xpath C# 使用xpath C#

Let's say that you have an XmlNode instance called node to start with. 假设您有一个名为node的XmlNode实例开始。 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: 然后,以下代码将为您提供该节点的曾祖父的第一个孩子的最后一个孩子的最后一个孩子:

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. 如果任何引用的节点碰巧为null,则将出现NullReferenceException。 So you will want to make a null check at each level: 因此,您将需要在每个级别进行空检查:

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> . 如果我正确理解您的问题,如果我们从节点<child somevalue="3"></child>我们想导航到<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. 即使您说要使用C#代码而不是XPath,在这种情况下,我仍认为XPath是可行的方法。 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: 例如,如果节点具有不同的标记名(如我的示例文档中所述),则可以改为:

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. 当然,这是假定node不为空,而是有效的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]->第一个名为“ grandparent”的子节点
  • /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

All the question you are asking are answered by the XmlNode class. XmlNode类将回答您提出的所有问题。 It has properties called ParentNode , FirstChild and LastChild which each return another XmlNode . 它具有称为ParentNodeFirstChildLastChild ,每个属性都返回另一个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, eg: 要在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 :: *”轴的缩写)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM