当 XML 文档包含名称空间时,Select 具有 XPath 的节点
Select Nodes with XPath when the XML document contains namespaces
我想 select 个 XML 文档的节点使用 XPath。但当 XML 文档包含 xml-namespaces 时它不起作用。
考虑到名称空间,如何使用 XPath 搜索节点?
这是我的 XML 文件(简体):
<ComponentSettings xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Company.Product.Components.Model">
<Created xmlns="http://schemas.datacontract.org/2004/07/Company.Configuration">2016-12-14T10:29:28.5614696+01:00</Created>
<LastLoaded i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/Company.Configuration" />
<LastSaved xmlns="http://schemas.datacontract.org/2004/07/Company.Configuration">2016-12-14T16:31:37.876987+01:00</LastSaved>
<RemoteTracer>
<TraceListener>
<Key>f987d7bb-9dea-49b4-a689-88c4452d98e3</Key>
<Url>http://192.168.56.1:9343/</Url>
</TraceListener>
</RemoteTracer>
</ComponentSettings>
我想获取 RemoteTracer 标签的 TraceListener 标签的所有 Url 标签。
这就是我获取它们的方式,但这仅在 XML 文档不使用名称空间的情况下有效:
componentConfigXmlDocument = new XmlDocument();
componentConfigXmlDocument.LoadXml(myXmlDocumentCode);
var remoteTracers = componentConfigXmlDocument.SelectNodes("//RemoteTracer/TraceListener/Url");
目前,我的解决方法是在加载 XML 之前使用正则表达式从 XML 原始字符串中删除所有命名空间。然后我的 SelectNodes() 工作正常。但这不是妥善的解决办法。
您这里有两个命名空间。首先是
http://schemas.datacontract.org/2004/07/Company.Product.Components.Model
根元素 (ComponentSettings
)、RemoteTracer
及其下方的所有元素都属于此命名空间。第二个命名空间是
http://schemas.datacontract.org/2004/07/Company.Configuration
Created
、LastLoaded
和Saved
属于其中。
要获得所需的节点,您必须在 xpath 查询中的所有元素前加上它们各自的名称空间前缀。将这些前缀映射到实际名称空间,您可以这样做:
var componentConfigXmlDocument = new XmlDocument();
componentConfigXmlDocument.LoadXml(File.ReadAllText(@"G:\tmp\xml.txt"));
var ns = new XmlNamespaceManager(componentConfigXmlDocument.NameTable);
ns.AddNamespace("model", "http://schemas.datacontract.org/2004/07/Company.Product.Components.Model");
ns.AddNamespace("config", "http://schemas.datacontract.org/2004/07/Company.Configuration");
然后这样查询:
var remoteTracers = componentConfigXmlDocument.SelectNodes("//model:RemoteTracer/model:TraceListener/model:Url", ns);
我想 select 个 XML 文档的节点使用 XPath。但当 XML 文档包含 xml-namespaces 时它不起作用。 考虑到名称空间,如何使用 XPath 搜索节点?
这是我的 XML 文件(简体):
<ComponentSettings xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Company.Product.Components.Model">
<Created xmlns="http://schemas.datacontract.org/2004/07/Company.Configuration">2016-12-14T10:29:28.5614696+01:00</Created>
<LastLoaded i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/Company.Configuration" />
<LastSaved xmlns="http://schemas.datacontract.org/2004/07/Company.Configuration">2016-12-14T16:31:37.876987+01:00</LastSaved>
<RemoteTracer>
<TraceListener>
<Key>f987d7bb-9dea-49b4-a689-88c4452d98e3</Key>
<Url>http://192.168.56.1:9343/</Url>
</TraceListener>
</RemoteTracer>
</ComponentSettings>
我想获取 RemoteTracer 标签的 TraceListener 标签的所有 Url 标签。 这就是我获取它们的方式,但这仅在 XML 文档不使用名称空间的情况下有效:
componentConfigXmlDocument = new XmlDocument();
componentConfigXmlDocument.LoadXml(myXmlDocumentCode);
var remoteTracers = componentConfigXmlDocument.SelectNodes("//RemoteTracer/TraceListener/Url");
目前,我的解决方法是在加载 XML 之前使用正则表达式从 XML 原始字符串中删除所有命名空间。然后我的 SelectNodes() 工作正常。但这不是妥善的解决办法。
您这里有两个命名空间。首先是
http://schemas.datacontract.org/2004/07/Company.Product.Components.Model
根元素 (ComponentSettings
)、RemoteTracer
及其下方的所有元素都属于此命名空间。第二个命名空间是
http://schemas.datacontract.org/2004/07/Company.Configuration
Created
、LastLoaded
和Saved
属于其中。
要获得所需的节点,您必须在 xpath 查询中的所有元素前加上它们各自的名称空间前缀。将这些前缀映射到实际名称空间,您可以这样做:
var componentConfigXmlDocument = new XmlDocument();
componentConfigXmlDocument.LoadXml(File.ReadAllText(@"G:\tmp\xml.txt"));
var ns = new XmlNamespaceManager(componentConfigXmlDocument.NameTable);
ns.AddNamespace("model", "http://schemas.datacontract.org/2004/07/Company.Product.Components.Model");
ns.AddNamespace("config", "http://schemas.datacontract.org/2004/07/Company.Configuration");
然后这样查询:
var remoteTracers = componentConfigXmlDocument.SelectNodes("//model:RemoteTracer/model:TraceListener/model:Url", ns);