使用XDocument解析具有名称空间的属性

时间:2016-10-25 17:38:35

标签: c# xml

我正在尝试使用LINQ的XDocument在他们的网站here上解析美国财政部提供的XML,并且在尝试以编程方式解析命名空间时遇到了问题。

XDocument doc = XDocument.Load("http://data.treasury.gov/feed.svc/DailyTreasuryYieldCurveRateData?$filter=year(NEW_DATE)%20eq%202016");

以下是XML的简化版本:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<feed xml:base="http://data.treasury.gov/Feed.svc/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
  <entry>
    <content type="application/xml">
      <m:properties>
        <d:NEW_DATE m:type="Edm.DateTime">2016-01-04T00:00:00</d:NEW_DATE>
        <d:BC_1YEAR m:type="Edm.Double">0.61</d:BC_1YEAR>
      </m:properties>
    </content>
  </entry>
</feed>

如果我对命名空间进行硬编码以访问m:*和d:*元素,因为它们在根中定义,如下所示:

XNamespace ns = "http://www.w3.org/2005/Atom";
XNamespace m = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";
XNamespace d = "http://schemas.microsoft.com/ado/2007/08/dataservices";

然后我可以用

解析日期的值
Convert.ToDateTime(doc.Root.Element(ns + "entry").Element(ns + "content").Element(m + "properties").Element(d + "NEW_DATE"));

它工作正常。但我宁愿不对命名空间进行硬编码,所以我试图使用类似的方法将它们从根中拉出来,但我得到null值:

XNamespace ns = doc.Root.Attribute("xmlns").Value;   // gives "http://www.w3.org/2005/Atom"
XNamespace m = doc.Root.Attribute(ns + "m").Value;   <--- ERROR because the attribute is null
XNamespace d = doc.Root.Attribute(ns + "d").Value;   <--- ERROR because the attribute is null

如果我检查dm属性,他们会使用名称空间http://www.w3.org/2000/xmlns/,它必须是默认名称。为什么他们不像元素一样使用xmlns属性中定义的命名空间?属性的顺序是否重要?或者,xmlns命名空间在显式使用时根本无法被覆盖?

1 个答案:

答案 0 :(得分:1)

属性的名称为xmlns:dxmlns由XML命名空间标准保留。 XML标准保留以xmlXML开头的任何属性或元素。属性xmlns指定元素或文档的默认命名空间。

 XNamespace d = doc.Root.Attribute(XNamespace.Xmlns+"d").Value;
 XNamespace m = doc.Root.Attribute(XNamespace.Xmlns+"m").Value;