我编写了一个XSLT来处理一组xml。
XSLT处理得很好,但是这些xml具有不同的编码集。目前我正在使用输出标签,如下所示:
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
但是这将强制更改编码为UTF-8
,但我需要与实际XML文档中的值相同。
我怎么才能得到这个?
但是这将强制将编码更改为UTF-8,但是我需要与实际XML文档中的值相同。
从XML的角度来看,使用什么编码没有区别,只要转义了适当的字符(XSLT处理器为您完成了转义)。每个XML处理器都需要支持UTF-8、UTF-16和US-ASCII。如果必须使用旧技术传输XML,否则会与UTF编码混淆(例如,一些较旧的FTP系统),则可以使用后者。
也就是说,在XSLT 2.0和3.0中,通过简单地使用xsl:result-document
和一个将XML加载为未解析文本的技巧,可以动态地完成此操作:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://example.com/functions">
<xsl:template match="/">
<xsl:result-document href="output-filename" encoding="{f:get-encoding(.)}">
<!-- your code -->
</xsl:result-document>
</xsl:template>
<xsl:function name="f:get-encoding">
<xsl:param name="node" />
<xsl:variable name="regex">^.*encoding=['"]([a-zA-Z0-9-]+)["'].*$</xsl:variable>
<xsl:value-of select="replace(tokenize(unparsed-text($node/base-uri()), 'n')[1], $regex, '$1')"/>
</xsl:function>
</xsl:stylesheet>
甚至在xsl:output
上使用
- 阴影属性(3.0特性)
- 内联匿名函数(XPath 3.0特性)
- 高阶函数,即将函数赋值给变量(XSLT 3.0 + XDM 3.0特性)并使用它(XPath 3.0特性,称为动态函数调用)
- let表达式(XPath 3.0特性)
- 静态参数和变量(XSLT 3.0特性)
简而言之,仅仅几行代码就展示了XSLT、XPath和XDM的一些新概念:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="input-url" static="yes" select="'yourinput.xml'" />
<xsl:variable name="get-encoding" static="yes" select='
let $regex := "^.*encoding=['""]([a-zA-Z0-9-]+)['""].*$"
return function($n) {
replace(tokenize(unparsed-text($n), "n")[1], $regex, "$1")
}' />
<!-- a shadow attribute is replaced with the actual attribute by the same name -->
<xsl:output _encoding="{$get-encoding($input-url)}" />
<xsl:template match="/">
<!-- your code here -->
<result />
</xsl:template>
</xsl:stylesheet>
此代码与Exselt一起正确运行,但我的Saxon版本(尚未)不支持它(它不允许在静态表达式中使用unparsed-text
),但我相信很快就会出现,或者是某种可配置的东西。我没有测试其他XSLT处理器。