仅在 XML 中的某些特定位置转换实体

converting entities only at some specific places in xml

提问人:Rahul 提问时间:7/7/2023 更新时间:7/7/2023 访问量:33

问:

以下代码从 xml 中取消对实体的转义:-

<xsl:stylesheet version='3.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
  
<xsl:output method="xml" omit-xml-declaration="no" use-character-maps="mdash" />

<xsl:character-map name="mdash">
<xsl:output-character character="&#x2014;" string="&amp;mdash;"/>
<xsl:output-character character="&amp;" string="&amp;amp;" />
<xsl:output-character character="&quot;" string="&amp;quot;" />
<xsl:output-character character="&apos;" string="&amp;apos;" />
<xsl:output-character character="&#167;" string="&amp;sect;"/>
<xsl:output-character character="&#36;" string="&amp;dollar;" />
<xsl:output-character character="&#47;" string="&amp;sol;" />
<xsl:output-character character="&#45;" string="&amp;hyphen;" />

</xsl:character-map>

<xsl:mode on-no-match="shallow-copy"/>

</xsl:stylesheet>

如果是 ,则实体在所有位置都从 ‐ 转换为 。&hyphen;&hyphen;

此外,对于一个特殊用户,实体将转换为 。&userdefined;&amp;userdefined;

现在对于下面的输入xml:-

<name id="123-24">abc&hyphen;pqr &userdefined;</name>

输出生成为:-

<name id="123&hyphen;24">abc&hyphen;pqr &amp;userdefined;</name>

在上面的输出中,只有在输入中定义了连字符实体时,才应将连字符实体转换为连字符。在这种情况下,123-24 被转换为 ,而不是 。123&hyphen;24123-24

同样对于一个特殊实体,应该保留而不是&userdefined;&userdefined;&amp;usedefined;

XSLT XML 解析 Saxon Saxparser XSLT-3.0

评论

0赞 Martin Honnen 7/7/2023
XSLT 数据模型不存储字符是字面上在输入中,还是使用字符引用或实体引用进行转义。因此,仅使用 XSLT 是无法解决这个问题的。有一个预处理器 LexEv 试图在标记中转换这些细节,并允许 XSLT 以这种方式处理它,但我不确定它是否更可用或保留。
0赞 michael.hor257k 7/7/2023
如果字符映射将字符串定义为连字符的输出,则写入输出的每个连字符(无论其来源如何)都将写为 。&amp;hyphen;&hyphen;

答:

0赞 Michael Kay 7/7/2023 #1

请记住,XSLT 处理模型由三个阶段组成:

  1. XML解析器将词法XML转换为节点树(XDM数据模型的实例)
  2. XSLT 转换器将此输入节点树转换为输出节点树
  3. 序列化程序将输出节点树转换为词法 XML

、 和 声明会影响步骤 3 的工作方式;这在 Saxon 中是可能的,因为 Saxon 包括 XSLT 转换器和串行器。但是,没有类似的方法可以影响步骤 1 的作用;这超出了 XSLT 处理器的控制范围,对于 Saxon,它是在 Saxon 无法控制的第三方产品中完成的。xsl:outputxsl:character-mapxsl:output-character

因此,XSLT 处理器不知道节点树中的字符最初是写为 还是写为 ,并且它无法找出。"‐""‐""&hyphen;"

当我自己遇到这个问题时,我已经解决了它,方法是在解析 XML 之前替换所有出现的 by,然后在序列化后转换回来。当然,这意味着转换必须牢记它将看到而不是 .&§§hyphen;