如何创建包含没有包装器的前缀的XElement?

时间:2019-02-26 13:59:04

标签: c# xml xelement

我正在尝试创建一个像这样的简单空XElement:

<dyn:Positions>
   <Vector2-Array>
   </Vector2-Array>
</dyn:Positions>

我具有上面定义的名称空间:

XNamespace dyn = "https://www.abc.at/dyn";

但是当我创建XElement时:

XElement positions = new XElement(dyn + "Positions", new XElement("Vector2-Array"));

结果如下:

<Positions xmlns="dyn">
  <Vector2-Array xmlns="" />
</Positions>

有可能不将其包装在另一个XElement中吗?因为我需要稍后在内部添加更多元素之后将该元素附加到另一个文档中。

2 个答案:

答案 0 :(得分:1)

我认为您希望Vector2-Array与位置在相同命名空间中,然后在输出中看不到它:

RTL_USER_PROCESS_PARAMETERS

这给

XElement positions = new XElement(dyn + "Positions", 
       new XElement(dyn + "Vector2-Array"));

<Positions xmlns="https://www.abc.at/dyn"> <Vector2-Array /> </Positions> 只是一种简写,以后将其合并到某些父XML中时,这并不重要。您应该非常确定所有内容都属于哪个名称空间。

答案 1 :(得分:0)

由于没有添加名称空间声明,因此dyn命名空间成为默认名称。

然后,当您添加不带名称空间的子元素时,必须添加不带名称空间的名称空间声明以指示其不在默认名称空间之内。

如果您的dyn命名空间不是默认的命名空间,请尝试以下代码:

XNamespace dyn = "https://www.abc.at/dyn";

XElement positions = new XElement(
    dyn + "Positions",
    new XAttribute(XNamespace.Xmlns + "dyn", "https://www.abc.at/dyn"),
new XElement("Vector2-Array"));

这将产生以下输出:

<dyn:Positions xmlns:dyn="https://www.abc.at/dyn">
  <Vector2-Array />
</dyn:Positions>

请注意,当您开始将此元素附加到其他文档时,如果名称空间不匹配,您可能会得到与原始问题类似的更多行为。

OP特别提出了将这个元素附加到另一个也包含名称空间声明的元素的主题。

我创建了以下代码进行测试:

        XNamespace dyn = "https://www.abc.at/dyn";

        XElement positions = new XElement(
            dyn + "Positions",
            new XAttribute(XNamespace.Xmlns + "dyn", "https://www.abc.at/dyn"),
        new XElement("Vector2-Array"));

        XElement root = new XElement(
            dyn + "root",
            new XAttribute(XNamespace.Xmlns + "dyn", "https://www.abc.at/dyn"));

        root.Add(positions);

使用调试器时,添加root之后的Positions元素的XML是这样的:

<dyn:root xmlns:dyn="https://www.abc.at/dyn">
  <dyn:Positions xmlns:dyn="https://www.abc.at/dyn">
    <Vector2-Array />
  </dyn:Positions>
</dyn:root>

因此,名称空间声明是重复的。

但是,在将XML保存或格式化为字符串时,可以使用SaveOption中的OmitDuplicateNamespaces

Console.WriteLine(root.ToString(SaveOptions.OmitDuplicateNamespaces));

其结果如下:

<dyn:root xmlns:dyn="https://www.abc.at/dyn">
  <dyn:Positions>
    <Vector2-Array />
  </dyn:Positions>
</dyn:root>

因为重复的名称空间声明实际上无能为力(即使它们很丑陋),但如果XML的显示很重要,则可以通过这种方式将其删除。

从功能上讲,只要名称空间声明重复,它们实际上就不会做任何事情。