XML命名空间问题C#

Posted

技术标签:

【中文标题】XML命名空间问题C#【英文标题】:XML namespace issue C# 【发布时间】:2020-03-04 04:00:16 【问题描述】:

我有一个 XML,我正在尝试从 XmlDocument 获取节点,但由于一些命名空间问题,它没有返回我想要的节点。

以下是我的 XML。

<?xml version="1.0" encoding="iso-8859-1"?>
<message xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.origoservices.com">
  <content>
    <application>
      <personal_client id="pc1">
        <title>Mr</title>
        <forenames>Test</forenames>
        <surname>SurName</surname>
        <sex>Male</sex>
      </personal_client>
      <personal_client id="pc2">
        <title>Mr</title>
        <forenames>Test</forenames>
        <surname>SurName</surname>
        <sex>Male</sex>
      </personal_client>
      <personal_client id="pc3">
        <title>Mr</title>
        <forenames>Test</forenames>
        <surname>SurName</surname>
        <sex>Male</sex>
      </personal_client>
    </application>
  </content>
</message>

以下是我用来从上述 xml 中获取所有 personal_client 节点的 C# 代码。

XmlDocument XMLDoc = new XmlDocument();
XMLDoc.PreserveWhitespace = true;
XMLDoc.Load("XML Loaded successfully");

XmlNamespaceManager nsmgr = new XmlNamespaceManager(XMLDoc.NameTable);
nsmgr.AddNamespace("origo", "http://www.origoservices.com");
nsmgr.PushScope();

XmlNodeList xnList = XMLDoc.SelectNodes("//origo:message/m_content/application/personal_client", nsmgr);

它一直返回 0 个节点,请帮忙。

【问题讨论】:

我建议你使用较新的 XML 对象,所以 XDocument XMLDoc.Load() 期望 xml 文件的路径作为参数,你为什么要传递消息? 【参考方案1】:

您需要为查询的每个元素指定命名空间,因为默认命名空间也适用于子节点。我已将您的示例 XML 放在一个名为 XmlFile1.xml 的文件中,并创建了以下示例:

var XMLDoc = new XmlDocument();
XMLDoc.Load("XmlFile1.xml");
XmlNamespaceManager nsmgr = new XmlNamespaceManager(XMLDoc.NameTable);
nsmgr.AddNamespace("origo", "http://www.origoservices.com");
XmlNodeList xnList = XMLDoc.SelectNodes("//origo:message/origo:content/origo:application/origo:personal_client", nsmgr);

此代码检索 3 个节点。

【讨论】:

是的,我也得到了节点,但你能告诉我为什么当我在根元素上指定 origo 时它不起作用。 @Rober 命名空间声明对子元素也有效。因此默认命名空间 (xmlns=) 对孩子也有效。因此,您还需要在 XPath 查询中指定它以便选择子节点。【参考方案2】:

这是另一种方式

//Using the file path
var clients = XDocument.Load(xmlFilePath)
               .Descendants(XName.Get("personal_client", "http://www.origoservices.com"));

//Using the file content
var clients = XDocument.Parse(xmlFileContent)
               .Descendants(XName.Get("personal_client", "http://www.origoservices.com"));

这样你就可以避免放置命名空间

.Descendants().Where(x => x.Name.LocalName == "personal_client");

【讨论】:

以上是关于XML命名空间问题C#的主要内容,如果未能解决你的问题,请参考以下文章

将带有命名空间和属性的 XML 转换为 C# 模型类

将命名空间添加到 xml 根节点 c#

C# |如何更改 XML 文档中的命名空间?

C# 在忽略命名空间的同时反序列化 xml

C# 使用多个可能的命名空间反序列化 xml

XML中命名空间之间的区别