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

Posted

技术标签:

【中文标题】.NET XmlWriter 中的正确名称空间管理【英文标题】:Proper name space management in .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。作为额外的奖励,我想覆盖默认命名空间,在编写节点时更改它。

【问题讨论】:

【参考方案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'

【讨论】:

这很有趣。不过,我使用的是 .NET 2.0。 @harpo:它是.Net 2.0(见msdn.microsoft.com/de-de/library/ms162617%28v=vs.80%29.aspx) XmlWriterSettings 是,但 NamespaceHandling 属性不是。 msdn.microsoft.com/en-us/library/…

以上是关于.NET XmlWriter 中的正确名称空间管理的主要内容,如果未能解决你的问题,请参考以下文章

.net 4.6.2 中的命名空间 system.web 错误中不存在类型或命名空间名称“HTTP”

啊Linux上PHP运行出错class XMLWriter'not found怎么解决

如何解决 .net 标准中的命名空间“System.Configuration”错误中不存在类型或命名空间名称“ConfigurationManager”?

添加带有前缀的开始元素,没有命名空间

“找不到类'XMLWriter'” php 中的错误| php55w-xml-5.5.24-1.w6.x86_64.rpm 丢失

AngularJS 中的模块和命名空间/名称冲突