【问题标题】:Efficient way to encode CDATA elements编码 CDATA 元素的有效方法
【发布时间】:2010-10-07 09:21:15
【问题描述】:

好的,我正在使用 StreamReader 从流中读取数据。流里面的数据不是xml,可以是任何东西。

基于输入 StreamReader,我正在使用 XmlTextWriter 写入输出流。基本上,当一切都说完后,输出流包含来自输​​入流的数据,这些数据包装在父元素中包含的元素中。

我的问题是双重的。数据以块的形式从输入流中读取,StreamReader 类返回 char[]。如果输入流中的数据包含“]]>”,则需要将其拆分为两个 CDATA 元素。首先,如何在 char 数组中搜索“]]>”?其次,因为我是分块阅读,所以“]]>”子字符串可能会被分成两个块,那么我该如何解释呢?

我可能会将 char[] 转换为字符串,然后对其进行搜索替换。这将解决我的第一个问题。在每次读取时,我还可以检查最后一个字符是否是“]”,以便在下一次读取时,如果前两个字符是“]>”,我将开始一个新的 CDATA 部分。

这看起来几乎没有效率,因为它涉及将 char 数组转换为字符串,这意味着要花费时间来复制数据,并占用两倍的内存。有没有更有效的方法,无论是在速度方面还是在内存方面?

【问题讨论】:

  • 我已经删除了我的答案,因为我已经决定我真的不知道 XmlTextWriter 是如何工作的。文档没有说出我的预期。

标签: c# .net xml cdata streamreader


【解决方案1】:

其次,因为我是分块阅读,所以“]]>”子字符串可能会分成两个块,那么我该如何解释呢?

确实,您必须将最后两个字符保留在队列中,而不是立即将它们吐出。然后当新的输入进入时,将其附加到队列中,并再次获取除最后两个字符之外的所有字符,对它们进行搜索和替换,然后输出。

更好:根本不用担心 CDATA 部分。它们只是为了方便手工创作而存在。如果您已经在进行搜索和替换,那么您没有理由不应该只用它们的预定义实体搜索和替换“”和“&”,并将它们包含在普通的文本节点中。由于这些是简单的单字符替换,因此您无需担心缓冲。

但是:如果您按照您所说的那样使用 XmlTextWriter,它就像为每个传入文本块调用 WriteString() 一样简单。

【讨论】:

    【解决方案2】:

    根据HOWTO Avoid Being Called a Bozo When Producing XML

    Don’t bother with CDATA sections

    XML 提供了两种转义方式 标记有效字符: 预定义实体和 CDATA 部分。 CDATA 部分仅 语法糖。两种选择 句法结构没有语义 区别。

    CDATA 部分很方便,当您 正在手动编辑 XML,需要 粘贴一大块文本 包括标记有效字符 (例如代码示例)。然而,当 使用序列化程序生成 XML, 序列化程序负责转义 自动并试图 微观管理逃避的选择 方法只开辟了可能性 错误。
    ...
    只有 、& 和(在属性值中)" 需要转义。

    只要对一小部分特殊字符进行编码/转义,它就应该可以工作。

    你是否必须自己处理逃跑是另一回事,但肯定是一个更容易解决的问题。

    然后将全部内容作为子文本节点附加到相关的 XML 元素。

    【讨论】:

      【解决方案3】:

      我知道 CDATA 的两个真实用例:

      一个在包含脚本的 XHTML 文档中:

      <script type="text/javascript">
      <![CDATA[
         function foo()
         {
            alert("You don't want <this> text escaped.");
         }
      ]]>
      </script>
      

      另一种是手工编写的 XML 文档,其中文本包含嵌入的标记,例如:

      <p>
         A typical XML element looks like this:
      </p>
      <p>
         <pre>
         <![CDATA[
            <sample>
               <text>
                  I'm using CDATA here so that I don't have to manually escape
                  all of the special characters in this example.
               </text>
            </sample>
         ]]>
         </pre>
      </p>
      

      在所有其他情况下,让 DOM(或 XmlWriter,或您用来创建 XML 的任何工具)转义文本节点就可以了。

      【讨论】:

      • 避免在脚本周围需要 CDATA 部分的一个好方法是使用 JavaScript 字符串文字转义:alert("You don't want \x3Cthis\x3E text escaped.");
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-03
      • 1970-01-01
      • 2010-11-01
      相关资源
      最近更新 更多