我使用XSL样式表(使用Apache Xalan)将XML转换为(某种)HTML。在XML中,可以有像—
这样的实体,它们必须保持原样。在XML文件的开头,我有一个引用这些实体的doctype。我应该怎样做才能使实体保持不变?
<!DOCTYPE article [
<!ENTITY mdash "—"><!-- em dash -->
]>
在XML文本中遇到SAXParseException: Recursive entity expansion, 'mdash'
时,给我&mdash
。
答案 0 :(得分:4)
定义和使用实体的方法是:
<!DOCTYPE xsl:stylesheet [<!ENTITY mdash "—">]>
<t>Hello — 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="—" string="&mdash;" />
</xsl:character-map>
</xsl:stylesheet>
当上述转换应用于同一XML文档(如上所示)时,输出为:
Hello — World!
答案 1 :(得分:1)
我应该怎样做才能让实体保持不变?
你做不到。在使用XSLT进行处理之前,必须通过XML解析器将实体引用解析为其内容,因为它们可能包含XPath需要匹配的元素和其他内容。与DOCTYPE混淆将无效。
但是,如果设置<xsl:output encoding="us-ascii">
,则应将后处理文档序列化为ASCII字符集,因此必须将em-dash编码为—
。
XSLT 2.0 proposes“字符映射”,它允许您指定所有—
字符必须编码为—
或任何其他序列,但它无法区分源—
中的—
和—
的{{1}}。如果您没有XSLT 2.0,则可以在输出文档上尝试使用简单的字符串替换hack来将—
替换为—
。这很狡猾,但只要您知道—
只会在文本和属性值内容中使用,就可以了。
规则“必须保持原样”通常是值得怀疑的。可怜的HTML解析器确实无法接受普通的Unicode字符,或者在编码信息丢失的最坏情况下,它至少应该能够处理数字字符引用。