【问题标题】:Proper name space management in .NET XmlWriter.NET XmlWriter 中的正确名称空间管理
【发布时间】:2010-09-06 19:19:57
【问题描述】:

我在工作中广泛使用 .NET XML 技术。我非常喜欢的一件事是 XSLT 引擎,更准确地说是它的可扩展性。然而,有一小块一直是烦恼的根源。没什么大不了的,或者我们不能忍受的东西,但它阻止了我们生成我们想要生成的漂亮 XML。

我们所做的其中一件事是内联转换节点并将节点从一个 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。作为额外的奖励,我想覆盖默认命名空间,在编写节点时更改它。

【问题讨论】:

    标签: c# .net xml xmlwriter


    【解决方案1】:

    我不确定这是您要查找的内容,但您可以在开始写入 Xml 流时使用这种代码:

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

    XmlWriter 应该记住它并且不再重写它。它可能不是 100% 防弹的,但它在大多数情况下都有效。

    【讨论】:

    • 应该,但没有。只是为了让我的脚远离我的嘴,尽管我现在要仔细检查。
    【解决方案2】:

    使用此代码:

    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>
    

    【讨论】:

    • @polish:几率?你的意思是?关键是人们复制/粘贴我们的示例,从 .NET 2.0 开始,没有人应该使用 new XmlTextWriter
    • 是的,这行得通。我一直在写很多类似的测试,直接使用 writer 时无法重现行为。我认为问题只出现在 XSLT 中。
    • @harpo:为什么我没有收到赏金?我想我回答了你的问题。
    • @polishchuk,你是对的。我以为它会在到期时自动发生。当我开始重现问题时,我会跟进一些代码。
    • @KirillPolishchuk 当我使用writer.WriteAttributeString("xmlns", Prefix, null, Ns); 时出现错误:The 'xmlns' attribute is bound to the reserved namespace 'http://www.w3.org/2000/xmlns/ 任何想法?使用 powershell
    【解决方案3】:

    你试过了吗?

    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'

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多