【问题标题】:How can I coerce XmlWriter to handle namespaces correctly?如何强制 XmlWriter 正确处理命名空间?
【发布时间】:2011-08-09 15:15:34
【问题描述】:

我想用 XmlWriter 写这样的东西(都在一个命名空间中):

<Root xmlns="http://tempuri.org/nsA">
  <Child attr="val" />
</Root>

但我似乎能得到的最接近的是:

<p:Root xmlns:p="http://tempuri.org/nsA">
  <p:Child p:attr="val" />
</p:Root>

使用此代码:

using System;
using System.Text;
using System.Xml;

namespace ConsoleApplication1
{
    internal class Program
    {
        private const string ns = "http://tempuri.org/nsA";
        private const string pre = "p";

        private static void Main(string[] args)
        {
            var sb = new StringBuilder();
            var settings = new XmlWriterSettings
                     {
                       NamespaceHandling = NamespaceHandling.OmitDuplicates, 
                                             /* ineffective */             
                       Indent = true
                     };
            using (XmlWriter writer = XmlWriter.Create(sb, settings))
            {
                writer.WriteStartElement(pre, "Root", ns);
                writer.WriteStartElement(pre, "Child", ns);
                writer.WriteAttributeString(pre, "attr", ns, "val"); 
                                             // breaks namespaces    
                writer.WriteEndElement();
                writer.WriteEndElement();
            }
            Console.WriteLine(sb.ToString());
        }
    }
}

当我不指定前缀时,我得到:

<Root xmlns="http://tempuri.org/nsA">
  <Child p2:attr="val" xmlns:p2="http://tempuri.org/nsA" />
</Root>

在整个生成的文档(p3、p4、p5 等)中都会产生重复命名空间中的这些“幻像”前缀。

当我不写属性时,我会得到我想要的输出(显然它缺少属性)。

为什么XmlWriter 不像我问的那样省略重复的命名空间?

【问题讨论】:

    标签: xml .net-4.0 xml-namespaces xmlwriter


    【解决方案1】:

    试试这样:

    using System;
    using System.Text;
    using System.Xml;
    
    class Program
    {
        private const string ns = "http://tempuri.org/nsA";
    
        static void Main()
        {
            var settings = new XmlWriterSettings
            {
                Indent = true
            };
            using (var writer = XmlWriter.Create(Console.Out, settings))
            {
                writer.WriteStartElement("Root", ns);
                writer.WriteStartElement("Child");
                writer.WriteAttributeString("attr", "", "val");
                writer.WriteEndElement();
                writer.WriteEndElement();
            }
        }
    }
    

    【讨论】:

    • 谢谢!这很有效,尽管完全违反直觉,因为属性也有命名空间。
    • 或者使用达林回答SO问题
    • 有人找到更好的解决方案吗?这个 ns 管理应该是自动的! :( 我特别喜欢这里的最后一个例子:msdn.microsoft.com/en-us/library/d1a1csew%28v=vs.80%29.aspx
    • 很高兴知道这会创建所需的输出,但是对此行为有什么解释吗?尤其是一个基于它的人可以平静地依赖看似写出的没有命名空间的属性,当使用XmlReader 读取时,仍然会附加预期的命名空间?
    猜你喜欢
    • 1970-01-01
    • 2010-09-06
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 2021-08-02
    • 1970-01-01
    • 2019-09-15
    • 1970-01-01
    相关资源
    最近更新 更多