Accessing namespaces through their namespace prefix
MSDN:
One of the advantages of using LINQ to XML with C# is that you do not have to use XML prefixes. When LINQ to XML loads or parses an XML document, each XML prefix is resolved to its corresponding XML namespace. After that, when you work with a document that uses namespaces, you almost always access the namespaces through the namespace URI, and not through the namespace prefix. When developers work with XML names in LINQ to XML they always work with a fully-qualified XML name (that is, an XML namespace and a local name).
a) Uhm, is the above quote claiming that in Linq to XML developers always work with fully-qualified XML names and thus always access namespaces through their namespace URI and not through namespace prefix?
But doesn't the following code access namespace through the prefix and not namespace URI ( and couldn't we also argue that in this example we aren't working with a fully qualified XML name ):
XNamespace aw = "http://www.adventure-works.com";
IEnumerable<XElement> c1 =
from el in root.Elements(aw + "Child")
select el;
b) why would in Linq to XML accessing namespaces through namespace URI be preferable to accessing them through a namespace prefix?
thank you
EDIT:
Why do you think your code sample uses a prefix?
I have no idea why I thought the above code uses a namespace prefix.
1) is there a way to access namespace through the prefix and not namespace URI ( for example, when trying to find ch开发者_开发知识库ild elements using XElement.Elements(Xname)
method )?
2) Besides a document having both a default namespace and an additional namespace declaration for the same namespace, are there any other examples I should be aware of where prefixes in input document may not get preserved when document is serialized back?
Why do you think your code sample uses a prefix? It uses an XNamespace
object which is the representation of the XML concept of a namespace in the LINQ to XML object model and API. Of course for ease of code the XNamespace is stored in a variable with a short name and that variable is used to construct an XName as the argument to the Elements
method but I don't see how any prefix is used or how the code in any way depends on the use of prefixes in the XML input.
Does that answer part a) of your question?
As for part b), what matters semantically in XML with namespaces is the namespace an element or attribute belongs to, prefixes don't matter. So it does not make any difference semantically whether you write
<root xmlns="http://example.com/ns1">
<foo>bar</foo>
</root>
or
<pf1:root xmlns:pf1="http://example.com/ns1">
<pf1:foo>bar</pf1:foo>
</pf1:root>
or
<pf2:root xmlns:pf2="http://example.com/ns1">
<pf2:foo>bar</pf2:foo>
</pf2:root>
And selecting any element nodes in those three samples with LINQ to XML is the same for all three samples, you simply define an XNamespace object
XNamespace ns1 = "http://example.com/ns1";
and then you can use e.g. Descendants(ns1 + "foo")
to access elements with local name foo
in the namespace http://example.com/ns1
.
So that is the main advantage, you write code to select elements or attributes based on the namespace they belong to, not based on any prefix used in certain input document.
There are certainly shortcomings in LINQ to XML's prefix "ignorance", for instance if you have a document with a default namespace but an additional namespace declaration for the same namespace then the order of the namespace declaration seems to decide how LINQ to XML serializes the document back. Below is a sample demonstrating that:
If we have two X(HT)ML input documents XMLFile1.xml
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xhtml="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Example</title>
</head>
<body>
<h1>Example</h1>
</body>
</html>
and XMLFile2.xml
<html xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Example</title>
</head>
<body>
<h1>Example</h1>
</body>
</html>
then the output with VS 2010/.NET 4.0 is
<?xml version="1.0" encoding="ibm850"?>
<xhtml:html xmlns="http://www.w3.org/1999/xhtml" xmlns:xhtml="http://www.w3.org/1999/xhtml" xml:lang="en">
<xhtml:head>
<xhtml:title>Example</xhtml:title>
</xhtml:head>
<xhtml:body>
<xhtml:h1>Example</xhtml:h1>
</xhtml:body>
</xhtml:html>
<?xml version="1.0" encoding="ibm850"?>
<html xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Example</title>
</head>
<body>
<h1>Example</h1>
</body>
</html>
So that certainly is a disadvantage of the LINQ to XML object model not storing any prefixes of element or attribute nodes, in that case the prefixes in the input document might not be preserved when you load and save back.
精彩评论