Как предотвратить появление пустых атрибутов xmlns в .NET 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 определенного протокола с использованием XML-XML, генерируемого XML. Чистый атрибут xmlns
может не нарушать или путать парсер, но он также не присутствует в любом использовании, которое я видел в этом протоколе.
Ответы
Ответ 1
Благодаря ответу Джереми Лью и немного более интересному, я понял, как удалить пустые атрибуты xmlns
: передать в корневом пространстве имен node при создании любого дочернего node, для которого вы не хотите иметь префикс на, Использование пространства имен без префикса в корневом каталоге означает, что вам нужно использовать то же пространство имен для дочерних элементов, чтобы они также не имели префиксов.
Фиксированный код:
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);
Спасибо всем всем вашим ответам, которые привели меня в правильном направлении!
Ответ 2
Это вариант ответа JeniT (спасибо вам очень много!)
XmlElement new_element = doc.CreateElement("Foo", doc.DocumentElement.NamespaceURI);
Это исключает необходимость копирования или повторения пространства имен во всем мире.
Ответ 3
Если элемент <loner>
в вашем образце XML не содержал в нем декларацию пространства имен xmlns
по умолчанию, то это было бы в пространстве имен whatever:name-space-1.0
, а не в пространстве имен. Если это вам нужно, вам нужно создать элемент в этом пространстве имен:
xml.CreateElement("loner", "whatever:name-space-1.0")
Если вы хотите, чтобы элемент <loner>
не содержал пространства имен, тогда созданный XML был именно то, что вам нужно, и вам не следует беспокоиться об атрибуте xmlns
, который был автоматически добавлен для вас.
Ответ 4
Поскольку root находится в неподписанном пространстве имен, любой дочерний элемент root, который хочет быть не-namespaced, должен быть выведен как ваш пример. Решением было бы префикс корневого элемента следующим образом:
<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);
Ответ 5
Если возможно, создайте класс сериализации, а затем выполните:
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
XmlSerializer serializer = new XmlSerializer(yourType);
serializer.Serialize(xmlTextWriter, someObject, ns);
Это безопаснее, и вы можете управлять пространствами имен с атрибутами, если вам действительно нужно больше контроля.
Ответ 6
Я решил проблему, используя шаблон Factory. Я создал объект Factory для объектов XElement. В качестве параметра для создания экземпляра Factory я указал объект XNamespace. Таким образом, каждый раз, когда XElement создается Factory, пространство имен будет добавляться автоматически. Вот код factory:
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);
}
}
Ответ 7
Да, вы можете помешать XMLNS из XmlElement.
Сначала Создается время, когда оно приходит: например,
<trkpt lat="30.53597" lon="-97.753324" xmlns="">
<ele>249.118774</ele>
<time>2006-05-05T14:34:44Z</time>
</trkpt>
Измените код: И передайте пространство имен xml
как это
Код С#:
XmlElement bookElement = xdoc.CreateElement("trkpt", "http://www.topografix.com/GPX/1/1");
bookElement.SetAttribute("lat", "30.53597");
bookElement.SetAttribute("lon", "97.753324");