代码之家  ›  专栏  ›  技术社区  ›  smwikipedia

将XPath与XML命名空间一起使用

  •  0
  • smwikipedia  · 技术社区  · 12 年前

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

    Tere是一个 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

    谢谢你。

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

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

    但以下代码仍然不起作用。这个 设置DiagConnectionString 仍然为空。为什么?

        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!");
    
    1 回复  |  直到 10 年前
        1
  •  3
  •   har07    12 年前

    默认命名空间具有不同的性质。默认名称空间声明的元素及其所有后代(没有不同的名称空间声明)在同一默认名称空间中考虑。因此,您也需要为所有后代使用前缀。这个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]
    

    ..或使用 XDocument 而不是 X元素 如果希望使用与for相同的XPath XmlDocument .

    推荐文章