【问题标题】:Use XPath with XML namespace将 XPath 与 XML 命名空间一起使用
【发布时间】:2014-10-13 07:18:42
【问题描述】:

我想用 XPath 处理下面的 xml:

<?xml version="1.0" encoding="utf-8"?>
<ServiceConfiguration serviceName="Cloud" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="4" osVersion="*" schemaVersion="2014-01.2.3">
  <Role name="Worker">
    <Instances count="2" />
    <ConfigurationSettings>
      <Setting name="setting1" value="value1" />
      <Setting name="setting2" value="value2" />
    </ConfigurationSettings>
    <Certificates>
    </Certificates>
  </Role>
</ServiceConfiguration>

根元素有一个xmlns

我的代码是这样的:

    XElement doc = XElement.Load(xmlFilePath);
    XmlNamespaceManager ns = new XmlNamespaceManager(new NameTable());
    ns.AddNamespace("prefix", "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration");
    XElement settingDiagConnectionString = doc.XPathSelectElement("//prefix:ServiceConfiguration/Role/ConfigurationSettings/Setting[1]", ns);  // <===== always return null.
    settingDiagConnectionString.SetAttributeValue("value", "hello, world!");

settingDiagConnectionString 始终为空。

为什么?

添加 1

谢谢har07。

为每个元素添加前缀后,以下代码起作用:

    XmlDocument doc = new XmlDocument();
    doc.Load(cscfgPath);
    XmlNamespaceManager ns = new XmlNamespaceManager(new NameTable());
    ns.AddNamespace("prefix", "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration");

    XmlNode settingDiagConnectionString = doc.SelectNodes("/prefix:ServiceConfiguration/prefix:Role/prefix:ConfigurationSettings/prefix:Setting[1]", ns)[0];
    settingDiagConnectionString.Attributes["value"].Value = "hello,world!";

但是下面的代码还是不行。 settingDiagConnectionString 仍然为空。为什么?

    XElement doc = XElement.Load(cscfgPath);
    XmlNamespaceManager ns = new XmlNamespaceManager(new NameTable());
    ns.AddNamespace("prefix", "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration");

    XElement settingDiagConnectionString = doc.XPathSelectElement("/prefix:ServiceConfiguration/prefix:Role/prefix:ConfigurationSettings/prefix:Setting[1]", ns);
    settingDiagConnectionString.SetAttributeValue("value", "hello, world!");

【问题讨论】:

    标签: c# xml xpath xml-namespaces default-namespace


    【解决方案1】:

    默认命名空间具有不同的性质。声明了默认命名空间的元素及其所有后代,没有在同一默认命名空间中考虑不同的命名空间声明。因此,您还需要为所有后代使用前缀。这个 XPath 对我来说很好用:

    XElement doc = XElement.Parse(xml);
    XmlNamespaceManager ns = new XmlNamespaceManager(new NameTable());
    ns.AddNamespace("prefix", "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration");
    XElement settingDiagConnectionString = doc.XPathSelectElement("//prefix:Role/prefix:ConfigurationSettings/prefix:Setting[1]", ns); 
    settingDiagConnectionString.SetAttributeValue("value", "hello, world!");
    

    更新:

    响应您的更新。那是因为您使用的是XElement。在这种情况下,doc 它本身已经代表 &lt;ServiceConfiguration&gt; 元素,因此您不需要在 XPath 中包含“ServiceConfiguration”:

    /prefix:Role/prefix:ConfigurationSettings/prefix:Setting[1]
    

    ..或使用XDocument 而不是XElement 如果您想使用与XmlDocument 相同的XPath 使其工作。

    【讨论】:

    • 谢谢,很有帮助。我更新了我的问题。
    • UPDATE 部分查看我的简短回复
    • 非常感谢您的回答。
    猜你喜欢
    • 1970-01-01
    • 2016-08-26
    • 2011-08-07
    • 1970-01-01
    • 1970-01-01
    • 2012-01-11
    • 2016-09-14
    • 2021-08-26
    • 1970-01-01
    相关资源
    最近更新 更多