开发者

Adding namespace attribute to XElement - how to prevent blank/empty namespace on child elements?

I need to read an xml document from a database record into an XDocument object in order for it to be deserialized. So that the deserialization will work, I need to apply a specific namespace to each of the level 1 elements. So XML looks a bit like this:

<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>

And I need it to look like this:

<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>

But when I run the following code to apply the namespace to each of the top-level elements within the Itinerary node:

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    

I get a blank xmln="" namespace attribute on each child element within that element, whic开发者_运维知识库h causes the deserialization to fail:

<Itinerary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Segments xmlns="http://myurl">
        <SegmentFlight xmlns="">
            <!-- etc ... -->
        </Segments>

How do I prevent the blank/empty namespace being added to each child element of the element to which the required namespace has been applied?


Remove the Elements from your For loop, it was causing all child elements to be processed, too.

    For Each elem In xmlDoc.Descendants("Itinerary") ''//.Elements
        elem.Name = ns + elem.Name.LocalName
    Next

EDIT

Sorry, that didn't work as you noticed, I hadn't had my coffee yet.

The reason that .Net is doing that is because you are resetting the default namespace in the middle of a document. If it didn't append the empty namespace to the child elements then all child elements of <Segments> would be automatically part of the http://myurl namespace. Maybe this is the result that you want but since you didn't tell .Net that its assuming you don't.

To say that in a different way, the output that you are getting says that <Itinerary> is in the empty namespace, <Segments> is in the http://myurl namespace and <SegmentFlight> is in the same empty namespace as <Itinerary>. If you want <SegmentFlight> to be part of the same namespace as <Segments> then you need to recursively apply the namespace. When you call ToString() .Net will output what you are expecting. Here's a recursive version:

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

This outputs:

<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>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜