使用XPath与XML命名空间 [英] Use XPath with XML namespace
问题描述
我想使用XPath处理下面的XML:
< XML版本=1.0编码=UTF -8>?;
< ServiceConfiguration服务名=云的xmlns =http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfigurationosFamily =4OSVERSION =*schemaVersion =2014-01.2。 3>
<角色名称=工人>
<实例数=2/>
< ConfigurationSettings>
<设定名=设置1值=值1/>
<设定名=设置2值=VALUE2/>
< / ConfigurationSettings>
<认证>
< /认证>
< /角色>
< / ServiceConfiguration>
泰雷的一个的xmlns
根元素。
我的代码是这样的:
的XElement文档= XElement.Load (xmlFilePath);
XmlNamespaceManager的NS =新的XmlNamespaceManager(新NameTable());
ns.AddNamespace(前缀,http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration);
的XElement settingDiagConnectionString = doc.XPathSelectElement(//前缀:ServiceConfiguration /角色/ ConfigurationSettings /设置[1],NS); //< =====总是返回null。
settingDiagConnectionString.SetAttributeValue(价值,你好,世界!);
但 settingDiagConnectionString
总是空。
为什么?
添加1
感谢har07
添加前缀每个元素后,下面的代码工作:
XmlDocument的DOC =新的XmlDocument();
doc.Load(cscfgPath);
XmlNamespaceManager的NS =新的XmlNamespaceManager(新NameTable());
ns.AddNamespace(前缀,http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration);
XmlNode的settingDiagConnectionString = doc.SelectNodes(/前缀:ServiceConfiguration /前缀:角色/前缀:ConfigurationSettings /前缀:设置[1],NS)[0];
settingDiagConnectionString.Attributes [值]值=你好,世界!;
但是,下面的代码仍然不工作。在 settingDiagConnectionString
仍是空。为什么?
的XElement文档= XElement.Load(cscfgPath);
XmlNamespaceManager的NS =新的XmlNamespaceManager(新NameTable());
ns.AddNamespace(前缀,http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration);
的XElement settingDiagConnectionString = doc.XPathSelectElement(/前缀:ServiceConfiguration /前缀:角色/前缀:ConfigurationSettings /前缀:设置[1],NS);
settingDiagConnectionString.SetAttributeValue(价值,你好,世界!);
默认命名空间具有不同的性质。其中默认命名空间中声明的元素,它的所有无相同的默认命名认为是不同的命名空间声明后裔。因此,你需要使用前缀为所有descendats为好。这个XPath对我来说工作得很好:
的XElement文档= XElement.Parse(XML);
XmlNamespaceManager的NS =新的XmlNamespaceManager(新NameTable());
ns.AddNamespace(前缀,http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration);
的XElement settingDiagConnectionString = doc.XPathSelectElement(//前缀:角色/前缀:ConfigurationSettings /前缀:设置[1],NS);
settingDiagConnectionString.SetAttributeValue(价值,你好,世界!);
更新:
在回答您的更新。这是因为你使用的XElement
。在这种情况下,商务部
它自身已经代表< ServiceConfiguration>
元素,所以你并不需要包括ServiceConfiguration 在XPath:
/前缀:角色/前缀:ConfigurationSettings /前缀:设置[1]
..或者使用的XDocument
而不是的XElement
如果要使其工作使用相同的XPath为的XmlDocument
。
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!");
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
.
这篇关于使用XPath与XML命名空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!