0

我想用 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

谢谢哈07。

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

    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!");
4

1 回答 1

3

默认命名空间具有不同的性质。声明了默认命名空间的元素及其所有后代,没有在同一默认命名空间中考虑不同的命名空间声明。因此,您还需要为所有后代使用前缀。这个 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 中包含“ServiceConfiguration”:

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

..或者如果您想使用与 for 相同的 XPath 使其工作,请使用XDocument而不是。XElementXmlDocument

于 2014-08-20T04:03:12.433 回答