【发布时间】:2018-10-01 10:57:40
【问题描述】:
我有一个由 Vector CANeds 生成的 xml 文件。此文件包含有关我想使用 C# 编写的工具读取的 CANopen 对象的信息。
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>
当我创建一个包含两个 ISO15745Profile 节点的 XmlNodeList 并循环遍历时,我得到了一个奇怪的行为。通过使用显式索引访问子节点,一切都按预期进行。当我使用 xpath 时,总是使用第一个节点。
代码sn-p:
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”节点之一,但这并没有改变结果。我可能把命名空间搞砸了……
【问题讨论】:
-
能不能把不能正常工作的代码贴出来...
-
尝试将
s_ns更改为".//ns:"以选择相对于当前节点的节点。 -
来自msdn.microsoft.com/en-us/library/ms256122(v=vs.110).aspx:
//- 递归下降;在任意深度搜索指定元素。当此路径运算符出现在模式的开头时,它表示从根节点递归下降。因此您正在搜索整个文档。 -
@quanik:太好了,就这么简单。非常感谢
-
@iMattView 我在my answer添加了一些解释