Как мне создать XElement, который содержит префикс без оболочки? - PullRequest
0 голосов
/ 26 февраля 2019

Я пытаюсь создать простой пустой XElement, например так:

<dyn:Positions>
   <Vector2-Array>
   </Vector2-Array>
</dyn:Positions>

У меня есть определенное выше пространство имен:

XNamespace dyn = "https://www.abc.at/dyn";

Но когда я создаю XElement:

XElement positions = new XElement(dyn + "Positions", new XElement("Vector2-Array"));

Получается так:

<Positions xmlns="dyn">
  <Vector2-Array xmlns="" />
</Positions>

Возможно ли это без упаковки в другой XElement?Потому что мне нужно, чтобы этот элемент был добавлен в другой документ позже, после того, как внутри будет добавлено больше элементов.

Ответы [ 2 ]

0 голосов
/ 26 февраля 2019

Я думаю, вы хотите, чтобы Vector2-Array находился в том же пространстве имен, что и Positions, и тогда вы не увидите его в выводе:

XElement positions = new XElement(dyn + "Positions", 
       new XElement(dyn + "Vector2-Array"));

это дает

<Positions xmlns="https://www.abc.at/dyn">
  <Vector2-Array />
</Positions>

запись dyn: - это просто сокращение, это не должно иметь значения, когда вы позже объедините это в некоторый родительский XML.Вы должны быть очень уверены, к какому пространству имен принадлежит все.

0 голосов
/ 26 февраля 2019

Поскольку вы не добавляете объявление пространства имен, пространство имен dyn становится значением по умолчанию.

Затем, когда вы добавляете дочерний элемент без пространства имен, необходимо добавить объявление пространства имен без пространства имен.чтобы указать, что оно не входит в пространство имен по умолчанию.

Если ваше пространство имен dyn не предназначено для пространства имен по умолчанию, попробуйте следующий код:

XNamespace dyn = "https://www.abc.at/dyn";

XElement positions = new XElement(
    dyn + "Positions",
    new XAttribute(XNamespace.Xmlns + "dyn", "https://www.abc.at/dyn"),
new XElement("Vector2-Array"));

Это приведет к следующему выводу:

<dyn:Positions xmlns:dyn="https://www.abc.at/dyn">
  <Vector2-Array />
</dyn:Positions>

Обратите внимание, что когда вы начнете добавлять этот элемент в другие документы, вы можете получить больше поведения, похожего на исходную проблему, если есть какие-либо несоответствия пространств имен.

ОП специально принеслатему добавления этого элемента к другому элементу, который также содержит объявление пространства имен.

Я создал этот код для проверки:

        XNamespace dyn = "https://www.abc.at/dyn";

        XElement positions = new XElement(
            dyn + "Positions",
            new XAttribute(XNamespace.Xmlns + "dyn", "https://www.abc.at/dyn"),
        new XElement("Vector2-Array"));

        XElement root = new XElement(
            dyn + "root",
            new XAttribute(XNamespace.Xmlns + "dyn", "https://www.abc.at/dyn"));

        root.Add(positions);

При использовании отладчика XML-кодЭлемент root после добавления Positions это:

<dyn:root xmlns:dyn="https://www.abc.at/dyn">
  <dyn:Positions xmlns:dyn="https://www.abc.at/dyn">
    <Vector2-Array />
  </dyn:Positions>
</dyn:root>

Таким образом, объявление пространства имен дублируется.

Тем не менее, существует SaveOption из OmitDuplicateNamespaces, который можно использовать при сохранении или форматировании XML в строку:

Console.WriteLine(root.ToString(SaveOptions.OmitDuplicateNamespaces));

В результате вы получите следующий результат:

<dyn:root xmlns:dyn="https://www.abc.at/dyn">
  <dyn:Positions>
    <Vector2-Array />
  </dyn:Positions>
</dyn:root>

Поскольку дублированные объявления пространства имен фактически ничего не делают (даже если они уродливы), они могут быть удалены таким образом, если отображение XML - важная вещь.

Функционально наличие дублированных объявлений пространства имен не делает 'на самом деле делать что угодно, пока они совпадают.

...