我需要将数据库记录中的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>
如何防止将空/空命名空间添加到已应用所需命名空间的元素的每个子元素?
答案 0 :(得分:1)
<击>
从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
命名空间中,{ {1}}与<SegmentFlight>
位于empty
名称空间中。如果您希望<Itinerary>
成为与<SegmentFlight>
相同的名称空间的一部分,那么您需要递归地应用名称空间。当您致电<Segments>
.Net将输出您期望的内容。这是一个递归版本:
ToString()
输出:
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