如何在 Firefox 中执行多个 XSL 转换过程?
How to do multiple XSL transformation passes in Firefox?
我试图在多个过程中使用包含的样式表转换 XML 文档,但是每当我尝试包含 exsl:node-set
来制作变量时,我都会放置转换后的 XML进入可用的 Firefox 无法解析并显示通知 Error loading stylesheet: An unknown error has occurred ()
.
我还没有发现任何其他技术可以在 XSLT 1.0 中进行多次转换,我不得不相信 Firefox does not support XSLT 2.0 and should support exsl:node-set
.
我的代码如下:
<?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>
预期结果是:
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" viewBox="0 0 26 14" xmlns="http://www.w3.org/2000/svg">
<rect width="2" height="2"/>
<rect x="4" width="2" height="2"/>
<rect x="8" width="2" height="2"/>
<rect x="12" width="2" height="2"/>
<rect x="16" width="2" height="2"/>
<rect x="20" width="2" height="2"/>
<rect x="24" width="2" height="2"/>
<rect x="24" y="4" width="2" height="2"/>
<rect x="20" y="4" width="2" height="2"/>
<rect x="16" y="4" width="2" height="2"/>
<rect x="12" y="4" width="2" height="2"/>
<rect x="8" y="4" width="2" height="2"/>
<rect x="4" y="4" width="2" height="2"/>
<rect y="4" width="2" height="2"/>
<rect y="8" width="2" height="2"/>
<rect x="4" y="8" width="2" height="2"/>
<rect x="8" y="8" width="2" height="2"/>
<rect x="12" y="8" width="2" height="2"/>
<rect x="16" y="8" width="2" height="2"/>
<rect x="20" y="8" width="2" height="2"/>
<rect x="24" y="8" width="2" height="2"/>
<rect x="24" y="12" width="2" height="2"/>
<rect x="20" y="12" width="2" height="2"/>
<rect x="16" y="12" width="2" height="2"/>
<rect x="12" y="12" width="2" height="2"/>
<rect x="8" y="12" width="2" height="2"/>
<rect x="4" y="12" width="2" height="2"/>
<rect y="12" width="2" height="2"/>
</svg>
exsl:node-set
在前缀为 exsl
的命名空间中描述函数 node-set
。与其他任何一样,默认情况下此前缀和命名空间不可用,但必须声明。
具体来说node-set
存在于EXSLT的Common模块中,其命名空间为http://exslt.org/common
.
这意味着您必须将 xmlns:exsl="http://exslt.org/common"
添加到 xsl:stylesheet
元素,这将使此命名空间在 exsl
前缀下可用并使您能够使用所需的函数为 exsl:node-set
。
除此之外,使用模式仅应用特定模板,将结果通过管道传输到变量并将其用作 apply-templates
的输入,如给定源中所示,这是正确的方法。
感谢Martin Honnen for 。
我试图在多个过程中使用包含的样式表转换 XML 文档,但是每当我尝试包含 exsl:node-set
来制作变量时,我都会放置转换后的 XML进入可用的 Firefox 无法解析并显示通知 Error loading stylesheet: An unknown error has occurred ()
.
我还没有发现任何其他技术可以在 XSLT 1.0 中进行多次转换,我不得不相信 Firefox does not support XSLT 2.0 and should support exsl:node-set
.
我的代码如下:
<?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>
预期结果是:
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" viewBox="0 0 26 14" xmlns="http://www.w3.org/2000/svg">
<rect width="2" height="2"/>
<rect x="4" width="2" height="2"/>
<rect x="8" width="2" height="2"/>
<rect x="12" width="2" height="2"/>
<rect x="16" width="2" height="2"/>
<rect x="20" width="2" height="2"/>
<rect x="24" width="2" height="2"/>
<rect x="24" y="4" width="2" height="2"/>
<rect x="20" y="4" width="2" height="2"/>
<rect x="16" y="4" width="2" height="2"/>
<rect x="12" y="4" width="2" height="2"/>
<rect x="8" y="4" width="2" height="2"/>
<rect x="4" y="4" width="2" height="2"/>
<rect y="4" width="2" height="2"/>
<rect y="8" width="2" height="2"/>
<rect x="4" y="8" width="2" height="2"/>
<rect x="8" y="8" width="2" height="2"/>
<rect x="12" y="8" width="2" height="2"/>
<rect x="16" y="8" width="2" height="2"/>
<rect x="20" y="8" width="2" height="2"/>
<rect x="24" y="8" width="2" height="2"/>
<rect x="24" y="12" width="2" height="2"/>
<rect x="20" y="12" width="2" height="2"/>
<rect x="16" y="12" width="2" height="2"/>
<rect x="12" y="12" width="2" height="2"/>
<rect x="8" y="12" width="2" height="2"/>
<rect x="4" y="12" width="2" height="2"/>
<rect y="12" width="2" height="2"/>
</svg>
exsl:node-set
在前缀为 exsl
的命名空间中描述函数 node-set
。与其他任何一样,默认情况下此前缀和命名空间不可用,但必须声明。
具体来说node-set
存在于EXSLT的Common模块中,其命名空间为http://exslt.org/common
.
这意味着您必须将 xmlns:exsl="http://exslt.org/common"
添加到 xsl:stylesheet
元素,这将使此命名空间在 exsl
前缀下可用并使您能够使用所需的函数为 exsl:node-set
。
除此之外,使用模式仅应用特定模板,将结果通过管道传输到变量并将其用作 apply-templates
的输入,如给定源中所示,这是正确的方法。
感谢Martin Honnen for