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

本文关键字:命名空间 XElement | 更新日期: 2023-09-27 17:55:20

我正在尝试通过代码(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>
命名空间

1 是默认命名空间(无前缀)并且命名空间 2 的前缀为"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());
}

但是,由于某种原因,这出错了。命名空间 1 中的某些元素被分配了一个奇怪的前缀"p1"。尽管它们使用相同的命名空间引用,但 LINQ 似乎认为 Name1Name2 的命名空间是不同的,并声明了两次:

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

如果我为命名空间 1 分配前缀或从命名空间 2 中删除属性,似乎不会出现此问题,但这无济于事,因为这无助于解决问题。

因此,问题的本质是:为什么 LINQ 将 XML 中的两个不同的命名空间声明分配给 NS1?如何将其配置为始终映射到默认命名空间?

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

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

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

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

  public static readonly XName Name2 = "name2";