Использовать XPath с пространством имен XML
Я хочу обработать XML ниже с 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>
Тере 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!");
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
само это уже представляет <ServiceConfiguration>
элемент, поэтому вам не нужно включать "ServiceConfiguration" в XPath:
/prefix:Role/prefix:ConfigurationSettings/prefix:Setting[1]
..или использовать XDocument
вместо XElement
если вы хотите, чтобы он работал, используя тот же XPath, что и для XmlDocument
,