.NET XmlWriter 中的正确命名空间管理

Proper name space management in .NET XmlWriter

提问人:Boaz 提问时间:8/26/2008 最后编辑:CœurBoaz 更新时间:1/30/2019 访问量:8800

问:

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

我们要做的一件事是内联转换节点,并将节点从一个 XML 文档导入到另一个 XML 文档。

可悲的是,当您将节点保存到(实际上是返回的任何节点)时,命名空间定义都会被扔到那里,无论它是否必要(先前定义)。你会得到以下 xml:XmlTextWriterXmlWriter.Create(Stream)

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

有没有人对如何说服.NET有效地定义其命名空间定义提出建议?

作为额外的奖励,我想覆盖默认命名空间,在编写节点时更改它。

C# .NET XML XmlWriter

评论


答:

1赞 Simon Mourier 6/21/2011 #1

我不确定这是否是你要找的,但是当你开始写入Xml流时,你可以使用这种代码:

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

XmlWriter 应该记住它,而不是再重写它。它可能不是 100% 防弹的,但它大部分时间都有效。

评论

0赞 harpo 6/22/2011
它应该,但事实并非如此。只是为了让我的脚不从我的嘴里出来,尽管我现在会仔细检查。
17赞 Kirill Polishchuk 6/26/2011 #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>

评论

4赞 John Saunders 6/27/2011
@polish:赔率?你是什么意思?关键是人们复制/粘贴我们的示例,并且没有人应该使用 .NET 2.0。new XmlTextWriter
0赞 harpo 6/27/2011
是的,这有效。我一直在写很多类似的测试,但直接使用编写器时无法重现该行为。我认为问题只出现在 XSLT 中。
0赞 harpo 6/28/2011
@polishchuk,你是对的。我以为它会在到期时自动发生。当我开始重现问题时,我将跟进一些代码。
3赞 Mohemmad K 4/16/2014
@KirillPolishchuk当我使用时出现错误:有什么想法吗?使用 PowerShellwriter.WriteAttributeString("xmlns", Prefix, null, Ns);The 'xmlns' attribute is bound to the reserved namespace 'http://www.w3.org/2000/xmlns/
2赞 habakuk 6/27/2011 #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”

评论

0赞 harpo 6/27/2011
这很有趣。不过,我在 .NET 2.0 中。
0赞 habakuk 6/28/2011
@harpo:它是 .Net 2.0(参见 msdn.microsoft.com/de-de/library/ms162617%28v=vs.80%29.aspx)
0赞 harpo 6/29/2011
XmlWriterSettings是,但属性不是。 msdn.microsoft.com/en-us/library/...NamespaceHandling