首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >检索Foreach循环中特定XML节点的特定子节点

检索Foreach循环中特定XML节点的特定子节点
EN

Stack Overflow用户
提问于 2019-08-23 00:54:25
回答 2查看 308关注 0票数 1

对于我的生活,我不明白为什么更多的人没有问这个问题,或者为什么我在网上找不到解决方案,除非碰巧没有解决方案。

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

代码语言:javascript
复制
<?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>

我的代码是这样工作的:

代码语言:javascript
复制
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吗?如果是,我该如何调整代码?

附注:这是一个统一使用的游戏。

EN

回答 2

Stack Overflow用户

发布于 2019-08-23 01:46:40

给Clay的评论投了赞成票,因为他真的很有帮助,而且是对的,并且给出了一个非常简单的答案(不需要我使用或转换为Linq)。

显然,没有足够的非Linq示例来过滤所有使用根的无用示例,也就是"//“。

接口的XMLnode列表行应该是:

代码语言:javascript
复制
XmlNodeList xmlInterfaces = vmNode.SelectNodes("ns:interface",nsmgr);

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

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

票数 2
EN

Stack Overflow用户

发布于 2019-08-23 01:37:18

我在一个控制台应用程序中尝试了这一点。确保你是using System.Xml.Linq;

代码语言:javascript
复制
string str = @"Your XML Here";
XDocument xDoc = XDocument.Parse(str);
var nodes = xDoc.Descendants("node").ToList(); // This gets you all <node>'s
var node = nodes.Where(n => n.Attribute("id").Value == "node-3").FirstOrDefault(); // This gets you just "node-3"
var interfaces = node.Descendants("interface").ToList();

‘'interfaces’包含:

代码语言:javascript
复制
<interface id="interface-6"></interface>
<interface id="interface-7"></interface>
<interface id="interface-8"></interface>

请注意,要使其正常工作,我必须将XML的第一行从:

代码语言:javascript
复制
<rspec type=manifest xmlns="link2ns" xmlns:jacks="jacksNSurl">

至:

代码语言:javascript
复制
<rspec>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57613951

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档