首页 > 解决方案 > 在 Foreach 循环中检索特定 XML 节点的特定子节点

问题描述

对于我的一生,我无法弄清楚为什么更多的人没有问过这个问题,或者为什么我无法在网上找到解决方案,除非碰巧没有。

一般的 XML 布局如下,但是接口的位置和接口计数可能会因 XML 文档而异(因此不能选择计算子节点):

<?xml version="1.0" ?>
<rspec type=manifest xmlns="link2ns" xmlns:jacks="jacksNSurl">
  <node id="node-1">
    <icon url="someurl" xmlns="jacksNSurl"/>
    <services>
      <login username="user1"/>
      <login username="user2"/>
    </services>
    <interface id="interface-0"></interface>
    <interface id="interface-1"></interface>
    <interface id="interface-2"></interface>
  </node>
  <node id="node-2">
    <icon url="someurl"/>
    <services>
      <login username="user1"/>
      <login username="user2"/>
    </services>
    <interface id="interface-3"></interface>
    <interface id="interface-4"></interface>
    <interface id="interface-5"></interface>
  </node>
  <node id="node-3">
    <icon url="someurl"/>
    <services>
      <login username="user1"/>
      <login username="user2"/>
    </services>
    <interface id="interface-6"></interface>
    <interface id="interface-7"></interface>
    <interface id="interface-8"></interface>
  </node>
</rspec>

我的代码工作如下:

List<MyClass> nodeList = new List<MyClass>();//Where I store what I got
XmlNodeList vmNodes = xmlDoc.GetElementsByTagName("node");//Gets all nodes
foreach (XmlNode vmNode in vmNodes) //go through each node and get stuff
{
    MyClass tempNode = new MyClass();//create a temporary class to be added to class list
   //get node ID and store it
   string nodeID = vmNode.Attributes["id"].Value;
   tempNode.ID = nodeID;

   //Here I want to get a temporary list of the interfaces and their for this specific node
   //The following line gives me all interfaces, NOT the ones of the current vmNode, which is all I want
   XmlNodeList xmlInterfaces = vmNode.SelectNodes("//ns:interface",nsmgr);
   //nsmgr is a namespace manager created at start of program and includes the following namespaces: xml, xmlns, ns, jacks, emulab, tour, xsi
   nodeList.Add(tempNode);
}

我的问题是我不能依赖每个节点的接口的位置或计数,因此使用 ChildNodes 然后通过计算节点来消除非接口子级将不起作用,因为接口计数和位置可能会从 XML 文档更改为 XML 文档。

我错过了什么吗?我浏览了微软的文档和包括这里在内的一堆论坛,我所找到的只是切题的答案,所有这些都会导致子节点计数方法或所有接口的列表(不仅仅是当前的接口) vmNode)。我应该改用 Linq,如果是,我该如何调整代码?

旁注:这是与统一使用来制作游戏的。

标签: c#xmlunity3d

解决方案


给 Clay 的评论一个赞成票,因为他确实提供了帮助并且是正确的,并且给出了一个非常简单的答案(不需要我使用或转换为 Linq)。

显然,没有足够的非 Linq 示例来过滤所有使用根的无用示例,即“//”。

我的接口的 XMLnode 列表行应该是:

XmlNodeList xmlInterfaces = vmNode.SelectNodes("ns:interface",nsmgr);

区别在于“//”,它告诉 C# 使用根 XML 节点,它是“ <rspec>”,而不是“ <node id=x>。通过去掉“//”,我告诉它使用当前的 XMLNode 元素,也vmNode就是parent 并且只获取具有选定名称“interface”的子节点。请注意,由于 xml 文档中存在命名空间,因此在我的 C# 代码中需要“ ns:<childnode name>”和“和”。nsmgr

我很惊讶没有更多这样的例子或有这个问题的人。希望其他人将来可以使用这篇文章并发现它有帮助,特别是因为它也使用命名空间。


推荐阅读