XmlWriter пишет пустой xmlns

Я использую следующий код для инициализации XmlDocument

XmlDocument moDocument = new XmlDocument();
moDocument.AppendChild(moDocument.CreateXmlDeclaration("1.0", "UTF-8", null));
moDocument.AppendChild(moDocument.CreateElement("kml", "http://www.opengis.net/kml/2.2"));

Позже в процессе я записываю в него некоторые значения, используя следующий код

using (XmlWriter oWriter = oDocument.DocumentElement.CreateNavigator().AppendChild())
{
  oWriter.WriteStartElement("Placemark");
  //....
  oWriter.WriteEndElement();
  oWriter.Flush();
}

В итоге, когда я сохраняю документ, я получаю следующий xml

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
  <Placemark xmlns="">
    <!-- -->   
  </Placemark>
</kml>

Как мне избавиться от пустых xmlns в элементе Placemark?

- ОТРЕДАКТИРОВАНА, ЧТОБЫ ПОКАЗАТЬ ИЗМЕНЕНИЕ НАПИСАННОЙ МАРКИ -
Если я помещаю пространство имен в запись метки, то в документ не добавляются никакие элементы.


person stevehipwell    schedule 13.07.2010    source источник
comment
Зачем вам заполненный xmlns? пространство имен такое же, как у родительского узла.   -  person onof    schedule 13.07.2010
comment
@onof - Мне не нужны заполненные xmlns, я пробовал сначала без, а потом подумал, что так лучше. См. Исправленный код.   -  person stevehipwell    schedule 13.07.2010


Ответы (6)


Я исправил проблему, создав документ со следующим кодом (без пространства имен в элементе документа)

XmlDocument moDocument = new XmlDocument(); 
moDocument.AppendChild(moDocument.CreateXmlDeclaration("1.0", "UTF-8", null)); 
moDocument.AppendChild(moDocument.CreateElement("kml"));

И, сохранив его с помощью следующего кода, чтобы установить пространство имен перед сохранением

moDocument.DocumentElement.SetAttribute("xmlns", msNamespace);
moDocument.Save(msFilePath);

Это действительно так, поскольку namespce требуется только в сохраненном XML-файле.

person stevehipwell    schedule 13.07.2010
comment
Это может быть правильно, но это плохая практика. - person Jason; 13.07.2010
comment
@Jason - Если вы не можете предложить «хороший» способ сделать это, тогда это не «плохая» практика; это единственный способ добиться этого! - person stevehipwell; 13.07.2010

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

Префикс xmlns используется только для объявления привязок пространства имен и по определению привязан к имени пространства имен http://www.w3.org/2000/xmlns/. Это НЕ ДОЛЖНО быть объявлено. Другие префиксы НЕ ДОЛЖНЫ быть привязаны к этому имени пространства имен, и оно НЕ ДОЛЖНО быть объявлено как пространство имен по умолчанию. Имена элементов НЕ ДОЛЖНЫ иметь префикса xmlns.

Источник: http://www.w3.org/TR/REC-xml-names/#ns-decl

person Community    schedule 25.04.2012

oWriter.WriteStartElement("Placemark"); должен работать, потому что у родительского узла уже есть нужное пространство имен.

person Hinek    schedule 13.07.2010
comment
Так у меня изначально был код, и он дает пустой xmlns. Я изменил свой код, чтобы отразить это, размещение пространства имен в записи метки фактически не позволит записать элементы. - person stevehipwell; 13.07.2010

Ты пробовал:

oWriter.WriteStartElement("kml", "Placemark", "kml");
person onof    schedule 13.07.2010
comment
Я так понимаю, вы имели в виду kml, а не klm; отредактировал на этом предположении. Это все еще не работает. - person stevehipwell; 13.07.2010

Тебе нужно было

oWriter.WriteStartElement("Placemark", "http://www.opengis.net/kml/2.2");

в противном случае элемент Placemark помещается в пустое пространство имен, поэтому атрибут xmlns="" добавляется при сериализации XML.

person Alohci    schedule 13.07.2010
comment
Вы имеете в виду, что делаете это, и он по-прежнему сериализуется с xmlns = в элементе Placemark? Или что-то другое? - person Alohci; 13.07.2010
comment
Даже если вы это сделаете, вы все равно получите xmlns = в элементе Placemark. - person stevehipwell; 19.07.2010

У меня сработал следующий код (источник):

XmlSerializer s = new XmlSerializer(objectToSerialize.GetType());
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("","");
s.Serialize(xmlWriter, objectToSerialize, ns);
person Artur    schedule 04.10.2019