Reputation: 1758
I am trying to parse the XML provided by the U.S. Treasury on their website here using LINQ's XDocument
, and I am running into issues when trying to parse out the namespaces programatically.
XDocument doc = XDocument.Load("http://data.treasury.gov/feed.svc/DailyTreasuryYieldCurveRateData?$filter=year(NEW_DATE)%20eq%202016");
Here is a stripped-down version of their 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>
If I hard-code the namespaces to access the m:* and d:* elements to the values as they're defined in the root like so:
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";
then I can parse out the value of a date with
Convert.ToDateTime(doc.Root.Element(ns + "entry").Element(ns + "content").Element(m + "properties").Element(d + "NEW_DATE"));
and it works fine. But I would rather not hard-code the namespaces, so I am trying to pull them out of the root using a similar method but I get null
values back:
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
It turns out if I inspect the d
and m
attributes, they use the namespace http://www.w3.org/2000/xmlns/
, which must be the default. Why don't they use the namespace defined in the xmlns
attribute like the elements do? Does the order of the attributes matter? Or maybe the xmlns
namespace simply can't be overridden when used explicitly?
Upvotes: 1
Views: 731
Reputation: 99997
The name of the attribute is xmlns:d
. xmlns
is reserved by the XML Namespaces standard. Any attribute or element starting with xml
or XML
is reserved by the XML standard. The attribute xmlns
specifies the default namespace for the element or document.
XNamespace d = doc.Root.Attribute(XNamespace.Xmlns+"d").Value;
XNamespace m = doc.Root.Attribute(XNamespace.Xmlns+"m").Value;
Upvotes: 1