在不使用字符映射的情况下保留 xslt 样式表输出中的实体

Retaining entity in xslt stylesheet output without using character-map

我们哪里错了?

当我在 saxon 上用 xslt 2 处理这个 xml 他:

 <data>
      <grab>Grab me and print me back &quot;</grab>
 </data>

使用此样式表:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:template match="/">
        <xsl:apply-templates select="/data/grab"/>
    </xsl:template>

    <xsl:template match="/data/grab">
        <node><xsl:value-of select="text()"/></node>
    </xsl:template>

</xsl:stylesheet>

我得到这个输出:

<?xml version="1.0" encoding="UTF-8"?><node>Grab me and print me back "</node>

但我想保留“在输出的 xml 中。因此我们需要添加一个字符映射:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:character-map name="specialchar">
        <xsl:output-character character="&quot;" string="&amp;quot;"/>
    </xsl:character-map>
    <xsl:output method="xml" indent="no"  use-character-maps="specialchar"/>
    <xsl:template match="/">
        <xsl:apply-templates select="/data/grab"/>
    </xsl:template>

    <xsl:template match="/data/grab">
        <node><xsl:value-of select="text()"/></node>
    </xsl:template>

</xsl:stylesheet>

其中保留了“实体...恕我直言,它看起来又冗长又丑陋,

这真的有必要吗?没有更优雅的选择吗?如果不是,这背后的原理是什么?

在架构上,XSLT 将 XDM 树转换为 XDM 树,它不会将词法 XML 转换为词法 XML。 XDM 树不区分 &quot;",就像它们区分 <a id="5"/><a id = '5'></a> 一样。事实上,你编写 XML 的方式中的任意和不相关的差异对 XSLT 程序员是隐藏的,这在很大程度上是设计使然,并且使得编写正确的转换变得容易得多。

现在肯定有保留实体引用的用例:特别是像 &author; 这样的语义实体引用可能在不同的场合采用不同的值。但是实体引用并不是满足该要求的特别好的解决方案; XInclude 通常更好。并且该论点不适用于 &quot; 之类的字符引用:很难找到一个好的用例来区别对待 &quot;",而且您肯定没有提供一个。

在实际层面上,Saxon 无法保留 &quot;,即使它想保留,因为它不知道它在那里:XML 解析器(将词法 XML 到 XDM) 不会通知应用程序的字符引用。同样,这是设计使然:理论上应用程序不应该知道也不应该关心。它的优点是我们不会从未能满足这种可能性的应用程序开发人员那里收到无数 SO 问题。