Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper name space management in .NET XmlWriter

I use .NET XML technologies quite extensively on my work. One of the things the I like very much is the XSLT engine, more precisely the extensibility of it. However there one little piece which keeps being a source of annoyance. Nothing major or something we can't live with but it is preventing us from producing the beautiful XML we would like to produce.

One of the things we do is transform nodes inline and importing nodes from one XML document to another.

Sadly , when you save nodes to an XmlTextWriter (actually whatever XmlWriter.Create(Stream) returns), the namespace definitions get all thrown in there, regardless of it is necessary (previously defined) or not. You get kind of the following xml:

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

Does anyone have a suggestion as to how to convince .NET to be efficient about its namespace definitions?

PS. As an added bonus I would like to override the default namespace, changing it as I write a node.

like image 530
Boaz Avatar asked Aug 25 '08 20:08

Boaz


2 Answers

Use this code:

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();
}

This code produced desired output:

<?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>
like image 103
Kirill Polishchuk Avatar answered Sep 25 '22 23:09

Kirill Polishchuk


Did you try this?

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

Interesting is the 'NamespaceHandling.OmitDuplicates'

like image 38
habakuk Avatar answered Sep 22 '22 23:09

habakuk