首页 > 解决方案 > 不是 url 时使用多个命名空间的 XML 选择

问题描述

想知道是否有人可以提供帮助,查看了其他帖子,但他们似乎在命名空间中有一个 URL,而我得到的第 3 方的输出没有。以前没有遇到过这样的 XML 结构;

<xml xmlns:z="#RowsetSchema" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882">
<s:Schema id="RowsetSchema">
<s:ElementType rs:updatable="true" content="eltOnly" name="row">
<s:AttributeType rs:name="Application Name" name="c0" rs:write="true" rs:number="1">
<s:datatype rs:precision="0" dt:maxLength="62" dt:type="string"/>
</s:AttributeType>
<s:AttributeType rs:name="Application ID" name="c1" rs:write="true" rs:number="2">
<s:datatype rs:precision="0" dt:maxLength="4" dt:type="int" rs:fixedlength="true"/>
</s:AttributeType>
<s:AttributeType rs:name="Site Name" name="c2" rs:write="true" rs:number="3">
<s:datatype rs:precision="0" dt:maxLength="42" dt:type="string"/>
</s:AttributeType>
<s:AttributeType name="TemplateID" rs:write="true" rs:number="4">
<s:datatype rs:precision="0" dt:maxLength="4" dt:type="int" rs:fixedlength="true"/>
</s:AttributeType>
<s:extends type="rs:rowbase"/>
</s:ElementType>
</s:Schema>
<rs:data>
<rs:insert>
<z:row TemplateID="3" c2="HostName" c1="1" c0="Master_Script"/>
<z:row TemplateID="3" c2="HostName" c1="2" c0="Network_Script"/>
<z:row TemplateID="3" c2="HostName" c1="3" c0="ACD_DN_App"/>
<z:row TemplateID="3" c2="HostName" c1="4" c0="NACD_DN_App"/>
</rs:insert>
</rs:data>
</xml>

我正在尝试获取 SelectNodes 中的z:row条目以获取c1c0属性。

在查看其他帖子后尝试在下面尝试,但没有快速得到任何地方。我确实注意到 XML 命名空间不是传统的 URL,不确定是否有影响或是否应该区别对待?

    appXML.LoadXml(wsResponse);
    XmlNamespaceManager nsMgr = new XmlNamespaceManager(appXML.NameTable);
    nsMgr.AddNamespace("rs", "urn:schemas-microsoft-com:rowset");
    nsMgr.AddNamespace("z", "#RowsetSchema");
    XmlNOdeList xmlRows = appXML.SelectNodes("/rs:data/rs:insert/z:row",nsMgr);

标签: c#xmlnamespaces

解决方案


XML 命名空间不是 URL 无关紧要。您是SelectNodes从 XML 文档级别 ( appXML) 做的,因此您需要在 XPath 中提及根元素,例如:

XmlNodeList xmlRows = appXML.SelectNodes("/xml/rs:data/rs:insert/z:row",nsMgr);
foreach(XmlElement row in xmlRows)
{
    Console.WriteLine(row.Attributes["c0"].Value);
}

dotnetfiddle demo

或者你可以SelectNodes从根元素级别做(注意,/XPath 表达式的开头总是引用文档,所以我们需要省略它以使 XPath 从根元素开始appXML.DocumentElement):

XmlNodeList xmlRows = appXML.DocumentElement.SelectNodes("rs:data/rs:insert/z:row",nsMgr);

或者,您可以使用descendant-or-self轴而不是默认轴来启动 XPath :

XmlNodeList xmlRows = appXML.SelectNodes("//rs:data/rs:insert/z:row",nsMgr);

推荐阅读