LINQ to XML: подавление избыточного атрибута пространства имен в дочерних узлах - PullRequest
2 голосов
/ 25 февраля 2010

Если узел принадлежит пространству имен, его дочерние элементы по умолчанию принадлежат тому же пространству имен. Поэтому нет необходимости указывать атрибут 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, но это кажется уродливым. Я ищу более очевидное решение, которое я почему-то упустил.

1 Ответ

1 голос
/ 10 марта 2010

Тьфу ... пространства имен - они будут моей смертью.

Вот, пожалуйста,

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-литералы с «я не знаю, как ты это называешь, но это все» parent.Add(something) - это плохая идея .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...