Сведения о вопросе

Oleksandrop

18:41, 22nd August, 2020

Теги

c#   .net   xml   xmlwriter    

Управление пространством собственных имен в .NET XmlWriter

Просмотров: 377   Ответов: 3

Я довольно широко использую технологии .NET XML в своей работе. Одна из вещей, которые мне очень нравятся, - это движок XSLT, точнее, его расширяемость. Однако есть один маленький кусочек, который продолжает быть источником раздражения. Ничего серьезного или чего-то такого, с чем мы не можем жить, но это мешает нам производить прекрасное XML, которое мы хотели бы произвести.

Одна из вещей, которые мы делаем, - это преобразование узлов inline и импорт узлов из одного документа XML в другой.

К сожалению, когда вы сохраняете узлы в XmlTextWriter (на самом деле все, что возвращает XmlWriter.Create(Stream) ), определения пространства имен попадают туда, независимо от того, является ли это необходимым (ранее определенным) или нет. Вы получаете вид следующего xml:

<root xmlns:abx="http://bladibla">  
     <abx:child id="A">  
         <grandchild id="B">
             <abx:grandgrandchild xmlns:abx="http://bladibla" />  
         </grandchild>  
     </abx:child>  
</root>

Есть ли у кого-нибудь предложения о том, как убедить .NET быть эффективным в своих определениях пространства имен?

PS. В качестве дополнительного бонуса я хотел бы переопределить пространство имен по умолчанию, изменяя его по мере написания узла.



  Сведения об ответе

FAriza

02:33, 28th August, 2020

Использовать этот код:

using (var writer = XmlWriter.Create("file.xml"))
{
    const string Ns = "http://bladibla";
    const string Prefix = "abx";

    writer.WriteStartDocument();

    writer.WriteStartElement("root");

    // set root namespace
    writer.WriteAttributeString("xmlns", Prefix, null, Ns);

    writer.WriteStartElement(Prefix, "child", Ns);
    writer.WriteAttributeString("id", "A");

    writer.WriteStartElement("grandchild");
    writer.WriteAttributeString("id", "B");

    writer.WriteElementString(Prefix, "grandgrandchild", Ns, null);

    // grandchild
    writer.WriteEndElement();
    // child
    writer.WriteEndElement();
    // root
    writer.WriteEndElement();

    writer.WriteEndDocument();
}

Этот код произвел желаемый результат:

<?xml version="1.0" encoding="utf-8"?>
<root xmlns:abx="http://bladibla">
  <abx:child id="A">
    <grandchild id="B">
      <abx:grandgrandchild />
    </grandchild>
  </abx:child>
</root>


  Сведения об ответе

dump

07:14, 25th August, 2020

Я не уверен, что это то, что вы ищете, но вы можете использовать этот вид кода, когда вы начинаете писать в поток Xml:

myWriter.WriteAttributeString("xmlns", "abx", null, "http://bladibla");

XmlWriter должен запомнить его и больше не переписывать. Это может быть не пуленепробиваемый 100%, но он работает большую часть времени.


  Сведения об ответе

DAAA

19:27, 9th August, 2020

Вы пробовали это сделать?

Dim settings = New XmlWriterSettings With {.Indent = True,
                                          .NamespaceHandling = NamespaceHandling.OmitDuplicates,
                                          .OmitXmlDeclaration = True}
Dim s As New MemoryStream
Using writer = XmlWriter.Create(s, settings)
    ...
End Using

Интересно, что такое 'NamespaceHandling.OmitDuplicates'


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться