Функция XElement Add добавляет xmlns = "" в XElement - PullRequest
8 голосов
/ 19 февраля 2010

У меня есть функция, которая генерирует xml для объекта списка:

public XDocument ToXML()
{
    foreach (var row in this)
    {
        var xml = row.ToXml();
        template.Root.Add(xml);
    }
    return template;
}

Шаблон . ToString () читает: <RootElement xmlns="urn:testTools">

xml гласит: <Example><SubElement>testData</SubElement></Example>

После выполнения функции добавления шаблон . ToString () читает: <RootElement xmlns="urn:testTools"><Example xmlns=""><SubElement>testData</SubElement></Example>

Так по какой-то причине было добавлено пустое пространство имен, как я могу предотвратить это?

Ответы [ 4 ]

9 голосов
/ 24 апреля 2010

Вот пример, который выводит xml без пустых пространств имен. Обратите внимание на причудливый Linq-центричный синтаксис rootNamespace + «MyElementName», который является секретом. Это то же пространство имен, что и весь документ, поэтому добавление xmlns не требуется. Это конкатенация XNamespace + строка, которая представляет собой перегрузку «+», которая работает для Linq и с которой Linq знает, как иметь дело. (Без Linq это может быть ошибка компиляции для объединения строки и не строкового типа). Обратите внимание, что это было выполнено для файла проекта C #, который является удобным XML-файлом. Выведите его на консоль или элемент управления richtextbox. Затем выньте «rootNamespace +» и обратите внимание на разницу.

        XDocument doc = null;

        using (StreamReader streamReader =
            new StreamReader(@"myXml.csproj"))
        {
            doc = XDocument.Load(streamReader, LoadOptions.None);
        }
        XNamespace rootNamespace = doc.Root.Name.NamespaceName;

        // A search which finds the ItemGroup which has Reference 
        // elements and returns the ItemGroup XElement.
        XElement element = doc.Descendants().Where(p => p.Name.LocalName == "ItemGroup"
            && p.Descendants().First<XElement>().Name.LocalName == "Reference").First<XElement>();

        // Create a completly new element with sub elements.
        XElement referenceElement = new XElement(rootNamespace + "Reference",
            new XElement(rootNamespace + "SpecificVersion", bool.FalseString),
            new XElement(rootNamespace + "HintPath", "THIS IS A HINT PATH"));

       // Add the new element to the main doc, to the end of the Reference elements.
        element.Add(referenceElement);

        // Add an attribute after the fact for effect.
        referenceElement.SetAttributeValue("Include", "THIS IS AN INCLUDE");

        rtb.Text = doc.ToString(SaveOptions.None);
8 голосов
/ 19 февраля 2010

Установите для пространства имен элементов Example и SubElement то же самое, что и для RootElement. Он добавляет xmlns = "", чтобы очистить пространство имен для этих элементов.

0 голосов
/ 15 марта 2010

Я решил это, заменив элементы регулярным выражением.Решение Фула не сработало, потому что у меня не всегда было точное пространство имен на тот момент кода.

Итак, вот мой грязный хак, который работает:

template = XDocument.Parse(new Regex("<ElementName.*>")
    .Replace(template.ToString(SaveOptions.DisableFormatting), "<ElementName>"));
0 голосов
/ 11 марта 2010

Возможно, ваш корень должен быть правильно закрыт:

 <RootElement xmlns="urn:testTools"> to <RootElement xmlns="urn:testTools"/> 
...