LINQ to XML:抑制子节点中的冗余命名空间属性

时间:2010-02-25 00:07:29

标签: vb.net linq linq-to-xml

如果某个节点属于某个命名空间,则它的子节点默认属于同一个命名空间。因此,没有必要为每个孩子提供xmlns属性,这很好。

然而

如果我创建两个这样的节点:

Dim parent = <parent xmlns="http://my.namespace.org"/>
Dim child = <child xmlns="http://my.namespace.org">value</child>

parent.Add(child)

Console.WriteLine(parent.ToString)

结果如下:

<parent xmlns="http://my.namespace.org">
  <child xmlns="http://my.namespace.org">value</child>
</parent>

但是,如果以不太方便的方式创建它们:

Dim parent = <parent xmlns="http://my.namespace.org"/>
Dim child As New XElement(XName.Get("child", "http://my.namespace.org")) With {.Value = "value"}

parent.Add(child)

Console.WriteLine(parent.ToString)

结果更令人满意:

<parent xmlns="http://my.namespace.org">
  <child>value</child>
</parent>

显然,我更喜欢使用第一种方式,因为它更直观,更容易编码。另外还有一个原因是不使用方法2 - 有时我需要用XElement.Parse创建节点,解析包含xmlns属性的字符串,它产生与方法1完全相同的结果。

所以问题是 - 如何获得方法2的漂亮输出,如方法1中那样创建节点?我看到的唯一选择是创建一个方法来克隆给定的XElement,有效地根据方法2模式重新创建它,但这看起来很难看。我正在寻找一个我忽略的更明显的解决方案。

1 个答案:

答案 0 :(得分:1)

呃...名称空间 - 他们将成为我的死亡。

你走了:

Dim ns As XNamespace = "http://my.namespace.org"
Dim parent = <<%= ns + "parent" %>/>
Dim child = <<%= ns + "child" %>>value</>
parent.Add(child)

为了能够使用XElement.Parse并使子节点与其父节点的命名空间保持同步,最好使用全局命名空间。在VB.NET中真的很容易做到。在模块/类的顶部,只需使用Imports,所有父级和子级都将使用此命名空间。例如:

Imports <xmlns="http://my.namespace.org">
Module Main
    Sub SomeSub()
        Dim child = <child>value</child>
        Dim parent = <parent><%= child %></parent>
        Console.WriteLine(parent.ToString)
    End Sub
End Module

请注意,首先创建<child/>元素。这同样适用于非默认命名空间,例如Imports <xmlns:p="http://parent.namespace.org">,然后使用<p:child/><p:parent/>进行创建。

我曾经读过,但还没有再找到,将XML Literals与我 - 不知道 - 你在调用它 - 但它是 - 那个 - parent.Add(something) - 混合坏主意。