XSLT - 转换 unicode 字符
XSLT - Transform unicode characters
我有一个这样的xml,
<doc>
<?PIValue ÒÓÔÕÖØ ÀÁÂÃÄÅ?>
<p>ÒÓÔÕÖØ ÀÁÂÃÄÅ</p>
</doc>
我对此 XML 进行了如下 XSLT 转换,
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="doc">
<doc>
<xsl:apply-templates/>
<p2><xsl:value-of select="processing-instruction('PIValue')"/></p2>
</doc>
</xsl:template>
<xsl:template match="p">
<p1>
<xsl:apply-templates/>
</p1>
</xsl:template>
上面的输出转换成这个,
<doc>
<?PIValue ÒÓÔÕÖØ ÀÁÂÃÄÅ?>
<p1>ÒÓÔÕÖØ ÀÁÂÃÄÅ</p1>
<p2>&#x00D2;&#x00D3;&#x00D4;&#x00D5;&#x00D6;&#x00D8; &#x00C0;&#x00C1;&#x00C2;&#x00C3;&#x00C4;&#x00C5;</p2>
</doc>
如您所见,<p>
元素中的 unicode 字符在输出中显示为普通文本(在 <p1>
元素中)。但是处理指令中的相同 unicode 字符没有显示,因为输出中有相关字符(在 <p2>
元素内)。
如何更改转换以在元素中也显示文本字符串。
expected output,
<doc>
<?PIValue ÒÓÔÕÖØ ÀÁÂÃÄÅ?>
<p1>ÒÓÔÕÖØ ÀÁÂÃÄÅ</p1>
<p2>ÒÓÔÕÖØ ÀÁÂÃÄÅ</p2>
</doc>
如果可以切换到 XSLT 3.0,则可以使用
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="doc">
<doc>
<xsl:apply-templates/>
<p2><xsl:value-of select="parse-xml-fragment(processing-instruction('PIValue'))"/></p2>
</doc>
</xsl:template>
<xsl:template match="p">
<p1>
<xsl:apply-templates/>
</p1>
</xsl:template>
</xsl:transform>
在 XML 中,字符引用(如 Ò
)在元素和属性内容中被识别,但在处理指令或注释中不被识别。所以在你的处理指令中,字符串 Ò
只是一个 8 个字符的字符串,而不是对单个字符 xD2.
的引用
如果您想将 Ò
字符串解释为字符引用,那么您可以将它们提交给 XML 解析器(正如 Martin Honnen 所建议的),或者您可以将它们解析出来 "by hand" 在你自己的代码中。没那么难: xsl:analyze-string
会提取 '00D2'
部分,写一个递归函数将十六进制转换为整数相当简单,然后最后一部分是调用 codepoints-to-string 转换整数代码到一个字符(=长度为一的字符串)。
我有一个这样的xml,
<doc>
<?PIValue ÒÓÔÕÖØ ÀÁÂÃÄÅ?>
<p>ÒÓÔÕÖØ ÀÁÂÃÄÅ</p>
</doc>
我对此 XML 进行了如下 XSLT 转换,
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="doc">
<doc>
<xsl:apply-templates/>
<p2><xsl:value-of select="processing-instruction('PIValue')"/></p2>
</doc>
</xsl:template>
<xsl:template match="p">
<p1>
<xsl:apply-templates/>
</p1>
</xsl:template>
上面的输出转换成这个,
<doc>
<?PIValue ÒÓÔÕÖØ ÀÁÂÃÄÅ?>
<p1>ÒÓÔÕÖØ ÀÁÂÃÄÅ</p1>
<p2>&#x00D2;&#x00D3;&#x00D4;&#x00D5;&#x00D6;&#x00D8; &#x00C0;&#x00C1;&#x00C2;&#x00C3;&#x00C4;&#x00C5;</p2>
</doc>
如您所见,<p>
元素中的 unicode 字符在输出中显示为普通文本(在 <p1>
元素中)。但是处理指令中的相同 unicode 字符没有显示,因为输出中有相关字符(在 <p2>
元素内)。
如何更改转换以在元素中也显示文本字符串。
expected output,
<doc>
<?PIValue ÒÓÔÕÖØ ÀÁÂÃÄÅ?>
<p1>ÒÓÔÕÖØ ÀÁÂÃÄÅ</p1>
<p2>ÒÓÔÕÖØ ÀÁÂÃÄÅ</p2>
</doc>
如果可以切换到 XSLT 3.0,则可以使用
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="doc">
<doc>
<xsl:apply-templates/>
<p2><xsl:value-of select="parse-xml-fragment(processing-instruction('PIValue'))"/></p2>
</doc>
</xsl:template>
<xsl:template match="p">
<p1>
<xsl:apply-templates/>
</p1>
</xsl:template>
</xsl:transform>
在 XML 中,字符引用(如 Ò
)在元素和属性内容中被识别,但在处理指令或注释中不被识别。所以在你的处理指令中,字符串 Ò
只是一个 8 个字符的字符串,而不是对单个字符 xD2.
如果您想将 Ò
字符串解释为字符引用,那么您可以将它们提交给 XML 解析器(正如 Martin Honnen 所建议的),或者您可以将它们解析出来 "by hand" 在你自己的代码中。没那么难: xsl:analyze-string
会提取 '00D2'
部分,写一个递归函数将十六进制转换为整数相当简单,然后最后一部分是调用 codepoints-to-string 转换整数代码到一个字符(=长度为一的字符串)。