对于我的生活,我不明白为什么更多的人没有问这个问题,或者为什么我在网上找不到解决方案,除非碰巧没有解决方案。
一般的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吗?如果是,我该如何调整代码?
附注:这是一个统一使用的游戏。
发布于 2019-08-23 01:46:40
给Clay的评论投了赞成票,因为他真的很有帮助,而且是对的,并且给出了一个非常简单的答案(不需要我使用或转换为Linq)。
显然,没有足够的非Linq示例来过滤所有使用根的无用示例,也就是"//“。
接口的XMLnode列表行应该是:
XmlNodeList xmlInterfaces = vmNode.SelectNodes("ns:interface",nsmgr);不同之处在于"//",它告诉C#使用根XML节点,即"<rspec>",而不是"<node id=x>“。通过去掉"//",我告诉它使用当前的接口元素(也称为vmNode )作为父节点,并且只获取具有选定名称”XMLNode“的子节点。请注意,由于xml文档中存在名称空间,因此在我的C#代码中需要使用"ns:<childnode name>”和nsmgr。
我很惊讶没有更多像这样的例子或者有这个问题的人。希望其他人将来可以使用这篇文章,并发现它是有帮助的,特别是因为它也使用名称空间。
发布于 2019-08-23 01:37:18
我在一个控制台应用程序中尝试了这一点。确保你是using System.Xml.Linq;
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’包含:
<interface id="interface-6"></interface>
<interface id="interface-7"></interface>
<interface id="interface-8"></interface>请注意,要使其正常工作,我必须将XML的第一行从:
<rspec type=manifest xmlns="link2ns" xmlns:jacks="jacksNSurl">至:
<rspec>https://stackoverflow.com/questions/57613951
复制相似问题