Как предотвратить пустые атрибуты xmlns в выводе from.NET ' S XmlDocument?


при создании XML из XmlDocument в .NET, пустое xmlns атрибут появляется при первом появлении элемента без вставляется связанное пространство имен; как это можно предотвратить?

пример:

XmlDocument xml = new XmlDocument();
xml.AppendChild(xml.CreateElement("root",
    "whatever:name-space-1.0"));
xml.DocumentElement.AppendChild(xml.CreateElement("loner"));
Console.WriteLine(xml.OuterXml);

выход:

<root xmlns="whatever:name-space-1.0"><loner xmlns="" /></root>

нужные выход:

<root xmlns="whatever:name-space-1.0"><loner /></root>

есть ли решение, применимое к XmlDocument код, а не то, что происходит после преобразование документа в строку с OuterXml?

мои рассуждения для этого, чтобы увидеть, если я могу соответствовать стандартному XML конкретного протокола с помощью XmlDocument-генерируемого XML. Пустой xmlns атрибут мая не сломать или запутать парсер, но он также не присутствует в любом использовании, которое я видел этого протокола.

7 105

7 ответов:

благодаря ответу Джереми Лью и немного больше играть вокруг, я понял, как удалить пустой xmlns атрибуты: передайте пространство имен корневого узла при создании любого дочернего узла, который вы хотите не иметь префикс. Использование пространства имен без префикса в корне означает, что вам нужно использовать это же пространство имен для дочерних элементов, чтобы они и нет приставок.

Исправленный Код:

XmlDocument xml = new XmlDocument();
xml.AppendChild(xml.CreateElement("root", "whatever:name-space-1.0"));
xml.DocumentElement.AppendChild(xml.CreateElement("loner", "whatever:name-space-1.0")); 
Console.WriteLine(xml.OuterXml);

спасибо всем за все ваши ответы что и привело меня в нужное русло!

Это вариант ответа JeniT (Спасибо большое кстати!)

XmlElement new_element = doc.CreateElement("Foo", doc.DocumentElement.NamespaceURI);

это устраняет необходимость копировать или повторять пространство имен везде.

если <loner> элемент в вашем примере XML не имел xmlns объявление пространства имен по умолчанию, тогда он будет в whatever:name-space-1.0 пространство имен вместо того, чтобы быть в пространстве имен нет. Если это то, что вы хотите, вам нужно создать элемент в этом пространстве имен:

xml.CreateElement("loner", "whatever:name-space-1.0")

если вы хотите <loner> элемент не должен быть в пространстве имен, то XML, который был создан именно то, что вам нужно, и вы не должны беспокоиться о xmlns атрибут, который был добавлен автоматически для тебя.

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

<w:root xmlns:w="whatever:name-space-1.0">
   <loner/>
</w:root>

код:

XmlDocument doc = new XmlDocument();
XmlElement root = doc.CreateElement( "w", "root", "whatever:name-space-1.0" );
doc.AppendChild( root );
root.AppendChild( doc.CreateElement( "loner" ) );
Console.WriteLine(doc.OuterXml);

если возможно, создайте класс сериализации, а затем выполните:

XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
XmlSerializer serializer = new XmlSerializer(yourType);
serializer.Serialize(xmlTextWriter, someObject, ns);

это безопаснее, и вы можете управлять пространствами имен с атрибутами, если вам действительно нужно больше контроля.

Я решил проблему с помощью шаблона "Фабрика". Я создал фабрику для объектов XElement. В качестве параметра для создания экземпляра фабрики я указал объект XNamespace. Таким образом, каждый раз, когда XElement создается фабрикой, пространство имен будет добавлено автоматически. Вот код фабрики:

internal class XElementFactory
{
    private readonly XNamespace currentNs;

    public XElementFactory(XNamespace ns)
    {
        this.currentNs = ns;
    }

    internal XElement CreateXElement(String name, params object[] content)
    {
        return new XElement(currentNs + name, content);
    }
}

Да вы можете предотвратить XMLNS от XmlElement . Первое время создания он приходит: вот так

<trkpt lat="30.53597" lon="-97.753324" xmlns="">
    <ele>249.118774</ele>
    <time>2006-05-05T14:34:44Z</time>
</trkpt>

изменить код : и передать пространство имен xml вот так

C# код:

XmlElement bookElement = xdoc.CreateElement("trkpt", "http://www.topografix.com/GPX/1/1");
bookElement.SetAttribute("lat", "30.53597");
bookElement.SetAttribute("lon", "97.753324");