【问题标题】:How to save XML without characters being escaped?如何在不转义字符的情况下保存 XML?
【发布时间】:2012-03-06 08:29:04
【问题描述】:

在我的 C# 应用程序中,XML 数据可能包含已经过预处理的任意元素文本,因此(除其他外)非法字符已被转换为其转义(xml 字符实体编码)形式。

示例:<myElement>this & that</myElement> 已转换为 <myElement>this & that</myElement>。

问题是当我使用 XmlTextWriter 保存文件时,'&' 被重新转义为<myElement>this & that</myElement>。我不希望字符串中有多余的 &。

另一个例子:<myElement>• bullet</myElement>,我的处理将其更改为<myElement>• bullet</myElement>,然后保存到<myElement>• bullet</myElement>。我想要输出到文件的只是<myElement>• bullet</myElement> 表单。

我在各种 XmlWriters 等上尝试了各种选项,但似乎无法获取原始字符串以正确获取输出。为什么 XML 解析器不能识别和重写已经有效的转义?

更新: 经过更多调试,我发现元素文本字符串(实际上是所有字符串,包括元素标签、名称、属性等)在被复制到 .net xml 对象数据时都会被编码(CDATA 是一个例外)由 System.Xml 下称为 XmlCharType 的内部类。所以这个问题与 XmlWriters 无关。看起来解决问题的最佳方法是在输出数据时取消转义数据,或者使用以下方法:

string output = System.Net.WebUtility.HtmlDecode(xmlDoc.OuterXml);

这可能会演变成自定义 XmlWriter 以保留格式等。

感谢所有有用的建议。

【问题讨论】:

  • 你能发布一个关于你如何使用XmlTextWriter的sn-p吗?如果你的 C# 已经创建了一个 XML 字符串,为什么还要使用 XmlTextWriter?
  • 所涉及的代码实际上有点广泛。我正在使用 XmlTextWriter 将 XML 序列化为文件。我需要,我可以创建一个重现行为的示例应用程序,但问题必须是众所周知的。如果这个问题已经得到解答,请提前道歉,但我似乎找不到任何相关的东西,除了下拉到看起来像黑客的 WriteRaw。
  • 只是一个想法,但 CDATA 块不应该允许这样做吗?

标签: c# encode xmlwriter


【解决方案1】:

好的,这是我想出的解决方案:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Versioning;
using System.Text;

namespace YourName {

    // Represents a writer that makes it possible to pre-process 
    // XML character entity escapes without them being rewritten.
    class XmlRawTextWriter : System.Xml.XmlTextWriter {
        public XmlRawTextWriter(Stream w, Encoding encoding)
            : base(w, encoding) {
        }

        public XmlRawTextWriter(String filename, Encoding encoding)
            : base(filename, encoding) {
        }

        public override void WriteString(string text) {
            base.WriteRaw(text);
        }
    }
}

然后像使用 XmlTextWriter 一样使用它:

        XmlRawTextWriter rawWriter = new XmlRawTextWriter(thisFilespec, Encoding.UTF8);
        rawWriter.Formatting = Formatting.Indented;
        rawWriter.Indentation = 1;
        rawWriter.IndentChar = '\t';
        xmlDoc.Save(rawWriter);

这无需取消编码或破解编码功能即可工作。

【讨论】:

    【解决方案2】:

    改为调用 xmlwriter.writeraw。但是检查字符是否有效还不够聪明。所以你必须自己检查,否则会生成一个无效的xml。

    【讨论】:

    • 是的,这是一个想法 - 但在测试您的建议时,我意识到元素文本实际上是在 XML 树中编码的。我原以为它是在输出上编码的,但显然是在输入或访问上。
    猜你喜欢
    • 1970-01-01
    • 2021-09-22
    • 2013-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-04
    相关资源
    最近更新 更多