属性上的XElement默认命名空间提供了意外行为

Tim*_*vis 3 c# xelement linq-to-xml xml-namespaces

我在创建包含默认命名空间和命名命名空间的XML文档时遇到问题,很难解释更容易显示我想要生成的内容...

<Root xmlns="http://www.adventure-works.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:SchemaLocation="http://www.SomeLocatation.Com/MySchemaDoc.xsd">
  <Book title="Enders Game" author="Orson Scott Card" />
  <Book title="I Robot" author="Isaac Asimov" />
</Root>
Run Code Online (Sandbox Code Playgroud)

但我最终得到的是......

<Root xmlns="http://www.adventure-works.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:SchemaLocation="http://www.SomeLocatation.Com/MySchemaDoc.xsd">
  <Book p3:title="Enders Game" p3:author="Orson Scott Card" xmlns:p3="http://www.adventure-works.com" />
  <Book p3:title="I Robot" p3:author="Isaac Asimov" xmlns:p3="http://www.adventure-works.com" />
</Root>
Run Code Online (Sandbox Code Playgroud)

我编写的用于生成此XML代码段的代码是......

  XNamespace aw = "http://www.adventure-works.com";
  XNamespace xsi = "http://www.w3.org/2001/XMLSchema-instance";
  XElement root = new XElement(aw + "Root",
      new XAttribute("xmlns", "http://www.adventure-works.com"),
      new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"),
      new XAttribute(xsi + "SchemaLocation", "http://www.SomeLocatation.Com/MySchemaDoc.xsd"),

      new XElement(aw + "Book",
        new XAttribute(aw + "title", "Enders Game"),
        new XAttribute(aw + "author", "Orson Scott Card")),
      new XElement(aw + "Book",
        new XAttribute(aw + "title", "I Robot"),
        new XAttribute(aw + "author", "Isaac Asimov")));
Run Code Online (Sandbox Code Playgroud)

基于MSDN上的示例

****编辑****

好的,通过一些更多的实验,我现在对XML名称空间如何工作非常困惑....

如果我删除了aw + theattribute我得到了我以后的东西......但现在看来我所追求的并不是我所期望的.我认为名称空间是从父母那里继承而来的,属性也不是这样吗?因为,这个读取属性的代码不能像我预期的那样工作......

  XElement xe = XElement.Parse(textBox1.Text);
  XNamespace aw = "http://www.adventure-works.com";
  var qry = from x in xe.Descendants(aw + "Book")
            select (string)x.Attribute(aw + "author");
Run Code Online (Sandbox Code Playgroud)

但是,如果我删除属性上的aw +就可以了,导致我假设我在默认命名空间中没有属性.它是否正确?

Jon*_*eet 6

好问题.我挖了一下,发现了这个XML规范:

默认名称空间声明适用于其范围内的所有未加前缀的元素名称.默认名称空间声明不直接应用于属性名称; 对无前缀属性的解释由它们出现的元素决定.

它后来继续给出这个例子:

例如,以下每个错误的空元素标记都是非法的:

<!-- http://www.w3.org is bound to n1 and n2 -->
<x xmlns:n1="http://www.w3.org" 
   xmlns:n2="http://www.w3.org" >
  <bad a="1"     a="2" />
  <bad n1:a="1"  n2:a="2" />
</x>
Run Code Online (Sandbox Code Playgroud)

但是,以下每个都是合法的,第二个是因为默认命名空间不适用于属性名称:

<!-- http://www.w3.org is bound to n1 and is the default -->
<x xmlns:n1="http://www.w3.org" 
   xmlns="http://www.w3.org" >
  <good a="1"     b="2" />
  <good a="1"     n1:a="2" />
</x>
Run Code Online (Sandbox Code Playgroud)

所以基本上,默认情况下属性名称看起来没有命名空间,这解释了你所看到的一切:)