【问题标题】:CDATA inside PCDATA handling in XML以 XML 格式处理 PCDATA 中的 CDATA
【发布时间】:2021-02-12 22:58:10
【问题描述】:

如果我们有以下 XML 元素:

<x>a &lt; b</x>

还有一个

<y>a<![CDATA[ < ]]>b</y>

xy 两个元素的值是否都为 a &lt; b?第二个例子是有效的、常见的、推荐的还是类似的?

AFAK y 具有三个子元素 - PCDATA a、CDATA &lt; 和 PCDATA b,一些库完全像这样解析它。另一方面,https://pugixml.org/ 仅返回 a 作为 x 的值(辅助函数)。

【问题讨论】:

    标签: xml cdata pcdata


    【解决方案1】:

    两者有根本区别:

    CDATA 表示 字符数据,而 PCDATA 表示 已解析的字符数据,这已经给我们一个提示解析器行为不同的正确方向,具体取决于它们的一致性级别。

    CDATA 部分是&lt;![CDATA[]]&gt; 标记之间的任何内容的严格转义。写在这之间的任何内容都不应该被 XML 处理器解析!符合标准的 XML 解析器只是忽略此处的任何内容,并将其传递给任何请求 XML 的应用程序(然后可以自行处理),而这些应用程序不可见。这就是为什么我们可以在这里放置任何通配符数据,而不会使 XML 失效。

    &amp;lt; 是一个实体,更具体地说是一个字符实体。实体是被内容替换的“占位符”或“标记”。这意味着,实体也是PCDATA(已解析字符数据)。它由 XML 解析器解析,然后解释它(尝试解析其内容),以便可以用它替换实体。

    对于数据的,我们可能需要了解更多关于请求 XML 的应用程序的信息。在 XML 处理工具(XSD、XSLT、XPath、XQuery 等)的领域内,在这两种情况下,它都应该作为 text()xs:string()xs:untypedAtomic 的任何 XPath 数据类型出现,具体取决于您用来访问它的功能。例如:

    let $t := <xml>Text <![CDATA[test]]> bla.</xml>
    return $t/data() instance of xs:untypedAtomic
    
    let $t := <xml>Text <![CDATA[test]]> bla.</xml>
    return $t/string() instance of xs:string
    
    let $t := <xml>Text <![CDATA[test]]> bla.</xml>
    return $t/text() instance of text()
    

    所有结果都是true

    但是,对于任何不使用 XML 数据模型的应用程序,结果应该只是文本,它位于元素标签之间。

    有一些 interesting note here 和一个关于这个和相关主题的完整线程。

    【讨论】:

    • 我知道CDATAPCDATA 之间的区别,我的问题更多是关于如何处理这个问题 - 我是否应该编写一个辅助函数来连接所有CDATAPCDATA 的子级一个元素到一个大字符串,或者只使用第一个(比如 pugixml,它会返回 a 作为 y 的值)或者将元素拒绝为“无效”或“不支持”之类的。
    • 对于 XML 域之外的任何内容,都表示相同:a &lt; b。由于我不明白,您想要的结果是什么(您如何处理从 XML 收到的数据)我不能推荐任何东西。不过,在一般情况下,我只会加入字符串值。
    猜你喜欢
    • 2013-12-26
    • 2010-10-29
    • 1970-01-01
    • 2014-09-07
    • 1970-01-01
    • 2015-09-16
    • 2010-10-25
    • 2015-05-14
    • 2021-01-30
    相关资源
    最近更新 更多