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

发布于 2024-07-04 12:55:36 字数 677 浏览 11 评论 0原文

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

我们所做的事情之一是内联转换节点并将节点从一个 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 对其命名空间定义有效提出建议?

附言。 作为额外的好处,我想覆盖默认名称空间,在编写节点时更改它。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

枯叶蝶 2024-07-11 12:55:36

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

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

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

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.

寒尘 2024-07-11 12:55:36

使用此代码:

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>

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>
潦草背影 2024-07-11 12:55:36

你尝试过这个吗?

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”

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'

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文