我有一个由Vector生成的CANeds文件。此文件包含有关我想用用CANopen编写的工具读取的C#对象的信息。
xml的(非常基本的)结构如下:
<ISO15745ProfileContainer xmlns="http://www.canopen.org/xml/1.0">
<ISO15745Profile>
<ProfileHeader></ProfileHeader>
<ProfileBody xsi:type="ProfileBody_Device_CANopen"</ProfileBody>
</ISO15745Profile>
<ISO15745Profile>
<ProfileHeader></ProfileHeader>
<ProfileBody xsi:type="ProfileBody_CommunicationNetwork_CANopen"</ProfileBody>
</ISO15745Profile>
</ISO15745ProfileContainer>当我创建一个包含两个XmlNodeList节点并循环通过的ISO15745Profile时,我会得到一个奇怪的行为。通过使用显式索引访问子节点,一切都如预期的那样。当我使用xpath时,总是使用第一个节点。
代码片段:
const string filepath = "CANeds1.xdd";
const string s_ns = "//ns:";
var mDataXML = new XmlDocument();
mDataXML.Load(filepath);
var root = mDataXML.DocumentElement;
XmlNamespaceManager nsm = new XmlNamespaceManager(mDataXML.NameTable);
nsm.AddNamespace("ns", root.Attributes["xmlns"].Value);
foreach (XmlNode node in root.ChildNodes) {
Console.WriteLine(" " + node.ChildNodes[1].Attributes["xsi:type"].Value);
Console.WriteLine(" " + node.SelectSingleNode(s_ns + "ProfileBody", nsm).Attributes["xsi:type"].Value);
}控制台输出:
ProfileBody_Device_CANopen
ProfileBody_Device_CANopen
ProfileBody_CommunicationNetwork_CANopen
ProfileBody_Device_CANopen由于节点引用了第二个节点,所以最后的输出应该是commNetwork。有人看到我的错误了吗?我已经尝试重命名一个"ISO15745Profile“节点,但是这并没有改变结果。我可能把命名空间搞砸了.
发布于 2018-10-01 16:11:40
对评论中给出的答复作进一步解释:
重要的一点是// XPath表达式。来自MSDN的定义是:
递归下降;在任意深度搜索指定的元素。当该路径运算符出现在模式的开头时,它指示从根节点递归下降。
这意味着以//开头的表达式将始终搜索整个文档,即使它是从特定的子注释中调用的。这就是为什么SelectSingleNode总是返回整个文档中的第一个匹配项。
要相对于调用选择方法的节点进行搜索,需要使用.操作符来指示当前上下文。
综合起来,以.//开头的表达式将搜索以下模式的所有出现,从当前节点开始。
在特定情况下,这意味着将//ns:更改为.//ns:以获得预期的结果。
https://stackoverflow.com/questions/52589641
复制相似问题