XElement中的重复命名空间(C#)

时间:2014-03-30 22:12:01

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

我正在尝试通过代码(LINQ to XML)生成XML,该代码遵循名称空间前缀的特定模式。我想生成以下输出,包括2个XML命名空间(示例说明案例;属性的顺序无关):

<name1 xmlns:space2="urn:schemas-upnp-org:namespace2/" xmlns="urn:schemas-upnp-org:namespace1/" name2="foo" space2:name4="demo">
  <name3>bar</name3>
</name1>

namespace1 必须是默认命名空间(无前缀), namespace2 的前缀为“space2”(我知道,但不要怪我 - 有标准要求这样的事情。)

我在C#中尝试了很多不同的方法。我认为最有可能的是:

public static readonly XNamespace NS1 = "urn:schemas-upnp-org:namespace1/";
public static readonly XNamespace NS2 = "urn:schemas-upnp-org:namespace2/";

public static readonly XName Name1 = NS1 + "name1";
public static readonly XName Name2 = NS1 + "name2";
public static readonly XName Name3 = NS1 + "name3";
public static readonly XName Name4 = NS2 + "name4"; // in namespace 2

void Test() {
    var y = new XElement(Name1,
            new XAttribute(XNamespace.Xmlns + "space2", NS2.NamespaceName),
            new XAttribute(Name2, "foo"),
            new XAttribute(Name4, "demo"),
            new XElement(Name3, "bar"));
    Trace.WriteLine(y.ToString());
}

出于某种原因,这是错误的。 namespace1中的某些元素被赋予了一个奇怪的前缀“p1”。尽管它们使用相同的命名空间引用,但似乎LINQ认为 Name1 Name2 的命名空间不同,并声明了两次:

<name1 xmlns:space2="urn:schemas-upnp-org:namespace2/" p1:name2="foo" space2:name4="demo" xmlns:p1="urn:schemas-upnp-org:namespace1/" xmlns="urn:schemas-upnp-org:namespace1/">
  <p1:name3>bar</p1:name3>
</name1>

如果我为 namespace1 分配前缀,或者如果我从 namespace2 中删除属性,似乎不会出现此问题,但这无济于事,因为这样做无济于事有问题。

所以问题的实质是:为什么LINQ在XML中为NS1分配两个不同的名称空间声明?如何配置为始终映射到默认命名空间?

1 个答案:

答案 0 :(得分:0)

您正在为属性“foo”指定名称空间,该属性为您的默认名称空间创建第二个映射。因此,有2个有效映射,并且可以为节点选择其中任何一个(可能是最新的)。

请注意,属性位于空命名空间中,除非它们具有显式前缀 - 因此您的代码实际上会生成不同的XML:您的属性名称为{urn:schemas-upnp-org:namespace2/}foo而不是{}foo

修复:不要为“foo”指定命名空间

  public static readonly XName Name2 = "name2";