我需要将数据库记录中的 xml 文档读入 XDocument 对象,以便对其进行反序列化。为了使反序列化起作用,我需要为每个 1 级元素应用一个特定的命名空间。所以 XML 看起来有点像这样:
<Itinerary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Segments>
<SegmentFlight>
</SegmentFlight>
<!-- more child elements -->
</Segments>
<References>
<!-- child elements -->
</References>
<Fares>
<!-- child elements -->
</Fares>
</Itinerary>
我需要它看起来像这样:
<Itinerary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Segments xmlns="http://myurl">
<SegmentFlight>
</SegmentFlight>
<!-- more child elements -->
</Segments>
<References xmlns="http://myurl">
<!-- child elements -->
</References>
<Fares xmlns="http://myurl">
<!-- child elements -->
</Fares>
</Itinerary>
但是,当我运行以下代码以将命名空间应用于 Itinerary 节点中的每个顶级元素时:
Dim xmlDoc As XDocument = XDocument.Load(New System.IO.StringReader(xmlStringFromDB))
Dim ns As XNamespace = "http://myurl"
For Each elem In xmlDoc.Descendants("Itinerary").Elements
elem.Name = ns + elem.Name.LocalName
Next
我在该元素中的每个子元素上都得到一个空白的 xmln=""命名空间属性,这会导致反序列化失败:
<Itinerary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Segments xmlns="http://myurl">
<SegmentFlight xmlns="">
<!-- etc ... -->
</Segments>
如何防止将空白/空命名空间添加到已应用所需命名空间的元素的每个子元素中?
最佳答案
删除 Elements
来自您的For
循环,它也导致所有子元素都被处理。
For Each elem In xmlDoc.Descendants("Itinerary") ''//.Elements
elem.Name = ns + elem.Name.LocalName
Next
编辑
对不起,你注意到了,我还没有喝咖啡。
.Net 这样做的原因是因为您正在重置文档中间的默认命名空间。如果它没有将空命名空间附加到子元素,那么
<Segments>
的所有子元素将自动成为 http://myurl
的一部分命名空间。也许这是您想要的结果,但由于您没有告诉 .Net 它假设您没有。换一种说法,你得到的输出是
<Itinerary>
在empty
命名空间,<Segments>
在http://myurl
命名空间和 <SegmentFlight>
在同一个empty
命名空间为 <Itinerary>
.如果你想要<SegmentFlight>
成为与 <Segments>
相同的命名空间的一部分那么你需要递归地应用命名空间。当您调用 ToString()
.Net 将输出您所期望的。这是一个递归版本:Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim xmlDoc As XDocument = XDocument.Load(New System.IO.StringReader(xmlStringFromDB))
Dim ns As XNamespace = "http://myurl"
ApplyNameSpaceToAllChildren(xmlDoc.Descendants("Itinerary").Elements(), ns)
Trace.WriteLine(xmlDoc.ToString())
End Sub
Private Sub ApplyNameSpaceToAllChildren(ByVal elements As IEnumerable(Of XElement), ByVal ns As XNamespace)
For Each elem In elements
elem.Name = ns + elem.Name.LocalName
If elem.HasElements Then
ApplyNameSpaceToAllChildren(elem.Elements, ns)
End If
Next
End Sub
这输出:
<Itinerary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Segments xmlns="http://myurl">
<SegmentFlight></SegmentFlight>
<!-- more child elements -->
</Segments>
<References xmlns="http://myurl">
<!-- child elements -->
</References>
<Fares xmlns="http://myurl">
<!-- child elements -->
</Fares>
</Itinerary>
关于vb.net - 向 XElement 添加命名空间属性 - 如何防止子元素上的空白/空命名空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5338387/