如果某个节点属于某个命名空间,则它的子节点默认属于同一个命名空间。因此,没有必要为每个孩子提供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模式重新创建它,但这看起来很难看。我正在寻找一个我忽略的更明显的解决方案。
答案 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)
- 混合坏主意。