我正在尝试使用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
如果我检查d
和m
属性,他们会使用名称空间http://www.w3.org/2000/xmlns/
,它必须是默认名称。为什么他们不像元素一样使用xmlns
属性中定义的命名空间?属性的顺序是否重要?或者,xmlns
命名空间在显式使用时根本无法被覆盖?
答案 0 :(得分:1)
属性的名称为xmlns:d
。 xmlns
由XML命名空间标准保留。 XML标准保留以xml
或XML
开头的任何属性或元素。属性xmlns
指定元素或文档的默认命名空间。
XNamespace d = doc.Root.Attribute(XNamespace.Xmlns+"d").Value;
XNamespace m = doc.Root.Attribute(XNamespace.Xmlns+"m").Value;