对属性的XElement默认命名空间提供了意想不到的行为(XElement default name

2019-09-22 05:27发布

我无法创建包含默认命名空间和指定的命名空间,很难解释容易只是展示一下我试图生成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>

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

<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>

我写生成此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")));

基于一个上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");

但是,如果我删除了AW +的属性其确定,导致我认为我不能在默认的命名空间属性。 这个对吗?

Answer 1:

好问题。 我挖了一下周围,发现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>

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

<!-- 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>

所以基本上,它看起来像属性名称不默认,这说明你已经看到的一切得到的命名空间:)



Answer 2:

XElement doc = XElement.Parse(ToXml());
doc.DescendantsAndSelf().Attributes().Where(a => a.IsNamespaceDeclaration).Remove();
var ele = doc.DescendantsAndSelf();
foreach (var el in ele)
    el.Name = ns != null ? ns + el.Name.LocalName : el.Name.LocalName;

对于谁比谁了2天试图寻找一个答案。



文章来源: XElement default namespace on attributes provides unexpected behaviour