在XML + XSLT中保持实体完整

时间:2010-04-28 12:46:54

标签: xml xslt html-entities xalan

我使用XSL样式表(使用Apache Xalan)将XML转换为(某种)HTML。在XML中,可以有像—这样的实体,它们必须保持原样。在XML文件的开头,我有一个引用这些实体的doctype。我应该怎样做才能使实体保持不变?

<!DOCTYPE article [
<!ENTITY mdash "&mdash;"><!-- em dash -->
]>
在XML文本中遇到SAXParseException: Recursive entity expansion, 'mdash'时,

给我&mdash

2 个答案:

答案 0 :(得分:4)

定义和使用实体的方法是

<!DOCTYPE xsl:stylesheet [<!ENTITY mdash "&#x2014;">]>
<t>Hello &mdash; World!</t>

使用最简单的XSLT样式表进行处理

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
</xsl:stylesheet>

生成正确的输出(包含mdash):

Hello — World!

重要

在XSLT 2.0中,可以使用<xsl:character-map>指令,以便某些指定字符由实体表示。在这种特殊情况下:

<xsl:stylesheet   version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
  <xsl:output omit-xml-declaration="yes" 
    use-character-maps="mdash"/>
  <xsl:character-map name="mdash">
    <xsl:output-character character="&#x2014;" string="&amp;mdash;" />
  </xsl:character-map>

</xsl:stylesheet>

当上述转换应用于同一XML文档(如上所示)时,输出为:

Hello &mdash; World!

答案 1 :(得分:1)

  

我应该怎样做才能让实体保持不变?

你做不到。在使用XSLT进行处理之前,必须通过XML解析器将实体引用解析为其内容,因为它们可能包含XPath需要匹配的元素和其他内容。与DOCTYPE混淆将无效。

但是,如果设置<xsl:output encoding="us-ascii">,则应将后处理文档序列化为ASCII字符集,因此必须将em-dash编码为&#8212;

XSLT 2.0 proposes“字符映射”,它允许您指定所有字符必须编码为&mdash;或任何其他序列,但它无法区分源中的&mdash;的{​​{1}}。如果您没有XSLT 2.0,则可以在输出文档上尝试使用简单的字符串替换hack来将替换为&mdash;。这很狡猾,但只要您知道只会在文本和属性值内容中使用,就可以了。

规则“必须保持原样”通常是值得怀疑的。可怜的HTML解析器确实无法接受普通的Unicode字符,或者在编码信息丢失的最坏情况下,它至少应该能够处理数字字符引用。