保留xml编码XSLT



我编写了一个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=[&apos;""]([a-zA-Z0-9-]+)[&apos;""].*$"
        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处理器。

最新更新