我们正在Mac OS X 10.11上使用Saxon PE 9.5.1.8处理UTF-8 XML输入文件。以下是转换:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="5.0" encoding="utf-8"/>
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="a">
<p><xsl:sequence select="text()"/></p>
</xsl:template>
</xsl:stylesheet>
以下是我们的XML输入文件的六进制转储:
$ hexdump -C utf.xml
00000000 3c 3f 78 6d 6c 20 76 65 72 73 69 6f 6e 3d 22 31 |<?xml version="1|
00000010 2e 30 22 20 65 6e 63 6f 64 69 6e 67 3d 22 55 54 |.0" encoding="UT|
00000020 46 2d 38 22 3f 3e 0a 3c 72 6f 6f 74 3e 0a 3c 61 |F-8"?>.<root>.<a|
00000030 3e 30 78 43 32 42 35 3d 22 3c 21 5b 43 44 41 54 |>0xC2B5="<![CDAT|
00000040 41 5b c2 b5 5d 5d 3e 22 3c 2f 61 3e 0a 3c 61 3e |A[..]]>"</a>.<a>|
00000050 30 78 43 32 38 44 3d 22 3c 21 5b 43 44 41 54 41 |0xC28D="<![CDATA|
00000060 5b c2 8d 5d 5d 3e 22 3c 2f 61 3e 0a 3c 2f 72 6f |[..]]>"</a>.</ro|
00000070 6f 74 3e 0a |ot>.|
00000074
重要字符是(i)行00000040,0xC2B5,表示为[..]
中的两个.
字符,以及(ii)行00000060,0xC28D,表示为[..]
中的两个子.
字符。
以下是如何从*nix命令shell生成XML输入文件:
echo '<?xml version="1.0" encoding="UTF-8"?>'
echo '<root>'
echo -e '<a>0xC2B5="<![CDATA[xc2xb5]]>"</a>' # micro sign
echo -e '<a>0xC28D="<![CDATA[xc2x8d]]>"</a>' # control character
echo '</root>'
我们的转换终止于:
SERE0014: Illegal HTML character: decimal 141"
十进制141是0x8D,它是我们的控制字符0xC28D的第二个字节。为什么Saxon会去掉0x8D字符并将其视为无效字符?我们期望Saxon将其视为有效的2字节UTF-8字符0xC28D的字节#2。
我们知道,当我们可以用method="xml"
创建HTML时;然而,这样做(i)不会发出我们致力于生成的HTML5,并且(ii)从HTML输出中删除0xC2字节。
如果我理解正确,那么您需要将UTF-8编码的XML文档中的Unicode字符UC28D
提供给XSLT。远至https://dotnetfiddle.net/HuNLpC告诉我,UTF-8中表示该字符的三字节序列是EC 8A 8D
,而不是十六进制转储中包含的两字节序列C2 8D
。所以我认为问题在于你的输入或输入生成,它不包含分别为你的角色创建正确的UTF-8编码。
另请参阅我的评论,如果您将XML字符引用与例如<root><a>0xC2B5="습"</a><a>0xC28D="슍"</a></root>
一起使用,那么Saxon(用9.5、9.6和9.7测试)确实会将样式表的输入转换为HTML文档,而不会抱怨任何错误或非法HTML字符。