如何在Firefox中进行多个XSL转换传递?

时间:2018-03-25 00:38:03

标签: xml firefox xslt exslt

我正在尝试使用包含的样式表在多个传递中转换XML文档,但每当我尝试包含exsl:node-set来生成变量时,我已将已转换的XML放入可用的Firefox中,无法解析通知{{ 1}}。
我没有找到任何其他技术在XSLT 1.0中进行多次转换传递,我被引导相信Firefox does not support XSLT 2.0should support exsl:node-set

我的代码如下:

Error loading stylesheet: An unknown error has occurred ()

预期结果是:

<?xml version="1.0"  encoding="UTF-8"?>
<?xml-stylesheet type="text/xml" href="#stylesheet"?>
<doc>
    <xsl:stylesheet id="stylesheet" version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:template match="xsl:stylesheet" mode="passone"/>
        <xsl:template match="@*|node()" mode="passone">
            <xsl:copy>
                <xsl:copy-of select="ancestor::node()[local-name()='inherit']/@*"/> <!-- take default from parent -->
                <xsl:copy-of select="@*"/> <!-- overwrite if applicable -->
                <xsl:apply-templates mode="passone"/>
            </xsl:copy>
        </xsl:template>
        <xsl:template match="@*|node()" mode="passtwo">
            <xsl:copy>
                <xsl:copy-of select="ancestor::node()[local-name()='inherit']/@*"/> <!-- take default from parent -->
                <xsl:copy-of select="@*"/> <!-- overwrite if applicable -->
                <xsl:apply-templates mode="passtwo"/>
            </xsl:copy>
        </xsl:template>
        <xsl:template match="@*|node()" mode="passthree">
            <xsl:copy>
                <xsl:copy-of select="ancestor::node()[local-name()='inherit']/@*"/> <!-- take default from parent -->
                <xsl:copy-of select="@*"/> <!-- overwrite if applicable -->
                <xsl:apply-templates mode="passthree"/>
            </xsl:copy>
        </xsl:template>
        <xsl:template match="*[local-name()='inherit']" mode="passthree">
            <xsl:apply-templates mode="passthree"/>
        </xsl:template>
        <xsl:template match="*[local-name()='template'][@define]" mode="passtwo"/>
        <xsl:template match="*[local-name()='template'][@insert]" mode="passtwo">
            <xsl:copy-of select="//*[local-name()='template'][@define=current()/@insert]/*"/>
            <xsl:apply-templates mode="passtwo"/>
        </xsl:template>
        <xsl:template match="/">
            <xsl:variable name="resultone">
                <xsl:apply-templates mode="passone" select="."/>
            </xsl:variable>
            <xsl:variable name="resulttwo">
                <xsl:apply-templates mode="passtwo" select="exsl:node-set($resultone)"/>
            </xsl:variable>
            <xsl:apply-templates mode="passthree" select="exsl:node-set($resulttwo)"/>
        </xsl:template>
    </xsl:stylesheet>


    <svg version="1.1" viewBox="0 0 26 14" xmlns="http://www.w3.org/2000/svg">
        <template define="row">
            <rect/>
            <rect x="4"/>
            <rect x="8"/>
            <rect x="12"/>
            <rect x="16"/>
            <rect x="20"/>
            <rect x="24"/>
        </template>
        <inherit width="2" height="2">
            <template insert="row"/>
            <inherit y="4">
                <template insert="row"/>
            </inherit>
            <inherit y="8">
                <template insert="row"/>
            </inherit>
            <inherit y="12">
                <template insert="row"/>
            </inherit>
        </inherit>
    </svg>
</doc>

1 个答案:

答案 0 :(得分:1)

exsl:node-set描述了名称空间中带有前缀node-set的函数exsl。与其他任何一样,此前缀和命名空间默认情况下不可用,但必须声明 具体而言,node-set存在于EXSLT的Common模块中,其命名空间为http://exslt.org/common 这意味着您必须将 xmlns:exsl="http://exslt.org/common" 添加到xsl:stylesheet元素,这将使此命名空间在exsl前缀下可用,并使您能够使用所需的功能为exsl:node-set

除此之外,使用模式仅应用特定模板,将结果传递给变量并将其用作apply-templates的输入,如给定源中所示,这是正确的方法。

感谢Martin Honnenthe pointer