Как предотвратить пустые атрибуты xmlns в выводе XmlDocument .NET?
-
02-07-2019 - |
Вопрос
При создании 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, сгенерированного XmlDocument.Пустой xmlns
атрибут может не сломать и не запутать парсер, но он также не присутствует ни в одном из известных мне случаев использования этого протокола.
Решение
Благодаря ответу Джереми Лью и еще немного поигравшись, я понял, как удалить пробел 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);
Это безопаснее, и вы можете управлять пространствами имен с помощью атрибутов, если вам действительно нужно больше контроля.
Я решил проблему, используя шаблон Factory.Я создал фабрику для объектов 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 -пространство имен, как это
Код С#:
XmlElement bookElement = xdoc.CreateElement("trkpt", "http://www.topografix.com/GPX/1/1");
bookElement.SetAttribute("lat", "30.53597");
bookElement.SetAttribute("lon", "97.753324");