Добавление атрибута пространства имен в XElement - как предотвратить пустое / пустое пространство имен на дочерних элементах?

Мне нужно прочитать 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>

Но когда я запускаю следующий код, чтобы применить пространство имен к каждому из элементов верхнего уровня в узле маршрута:

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>

Как предотвратить добавление пустого / пустого пространства имен к каждому дочернему элементу элемента, к которому применено требуемое пространство имен?

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 пространство имен и <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>
Другие вопросы по тегам