Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I want to process the xml below with XPath:

<?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's a xmlns for the root element.

My code is this:

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

But the settingDiagConnectionString is always null.

Why?

Add 1

Thanks har07.

After adding prefix for every element, the following code works:

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

But the following code still don't work. The settingDiagConnectionString is still null. Why?

    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!");
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
187 views
Welcome To Ask or Share your Answers For Others

1 Answer

Default namespace has different nature. The element where the default namespace declared and all of it's descendant without different namespace declaration considered in the same default namespace. Therefore, you need to use the prefix for all descendats as well. This XPath worked fine for me :

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

UPDATE :

Responding to your update. That's because you're using XElement. In this case, doc it self already represents <ServiceConfiguration> element so you don't need to include "ServiceConfiguration" in the XPath :

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

..or use XDocument instead of XElement if you want to make it work using the same XPath as for XmlDocument.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...