Proper name space management in .NET XmlWriter

别来无恙 提交于 2021-02-06 10:10:41

问题


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.


回答1:


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>



回答2:


I'm not sure this is what you're looking for, but you can use this kind of code when you start writing to the Xml stream:

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

The XmlWriter should remember it and not rewrite it anymore. It may not be 100% bulletproof, but it works most of the time.




回答3:


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'



来源:https://stackoverflow.com/questions/26743/proper-name-space-management-in-net-xmlwriter

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!