使用XPath与XML命名空间 [英] Use XPath with XML namespace

查看:158
本文介绍了使用XPath与XML命名空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用XPath处理下面的XML:

 < XML版本=1.0编码=UTF -8>?; 
< ServiceConfiguration服务名=云的xmlns =htt​​p://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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆