使用XPath和XML名称空间

本文关键字:空间 XML XPath 使用 | 更新日期: 2023-09-27 18:18:56

我想用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!");

使用XPath和XML名称空间

默认命名空间具有不同的性质。在同一默认名称空间中声明了默认名称空间的元素及其所有未声明不同名称空间的后代元素。因此,您还需要为所有的后代使用前缀。这个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本身已经表示<ServiceConfiguration>元素,因此您不需要在XPath中包含" servicecconfiguration":

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

. .或者使用XDocument而不是XElement,如果您想让它使用与XmlDocument相同的XPath。