【问题标题】:XElement default namespace on attributes provides unexpected behaviour属性上的 XElement 默认命名空间提供了意外的行为
【发布时间】:2009-08-05 05:47:29
【问题描述】:

我在创建包含默认命名空间和命名命名空间的 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 sn-p 编写的代码是这样的......

  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")));

基于example on 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 + 就可以了,这导致我假设我不能在默认命名空间中拥有属性。这是正确的吗?

【问题讨论】:

    标签: c# linq-to-xml xml-namespaces xelement


    【解决方案1】:

    好问题。我挖了一下,发现this bit of the XML spec

    默认命名空间声明 适用于所有无前缀元素 其范围内的名称。默认 命名空间声明不适用 直接到属性名称;这 无前缀的解释 属性是由 它们出现的元素。

    后面继续举这个例子:

    例如,每个错误的空元素标签在下面都是非法的:

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

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

    【讨论】:

    • 确实很有趣。 XML 命名空间不好玩 ;-)
    • 同意,尽管 LINQ to XML 使它们比我见过的任何其他框架都更易于使用。
    【解决方案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 天时间试图找到答案的人。

    【讨论】:

      猜你喜欢
      • 2011-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-25
      • 1970-01-01
      • 2018-07-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多