我已经编写了一个使用15个XSL样式表管道的应用程序,并且我正在开始调整其性能。它的设计是可移植的,因此它可以在网络浏览器环境和桌面环境中运行。在桌面上,我认为将样式表保持为多个转换的管道是有意义的,因为这可以让每个单独的转换在其自己的线程中运行,这对于具有多个核心的CPU来说可以非常高效。然而,不仅浏览器环境是单线程的,在大多数浏览器中,暴露于JavaScript的XSL处理API需要将每个单独转换的结果解析回DOM对象,这看起来效率不高。我认为,如果可能的话,在浏览器环境的上下文中运行时,将所有样式表组合成单个样式表将是有利的。我对如何用exsl:node-set(大多数浏览器支持)可以实现这个想法有所了解,但是我不清楚我想象的技术是否可以推广。是否有一种将XSL样式表管道转换为单个XSL样式表的通用技术,以便保留完整管道的语义?自动化解决方案将是理想的。是否有将XSL转换管道组合成单个转换的技术?
4
A
回答
2
有一种技术,允许独立变换链接在一起,其中第k个变换的输出是第(k + 1)个变换的输入。
下面是一个简单的例子:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
exclude-result-prefixes="ext xsl">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:variable name="vrtfPass1">
<xsl:apply-templates select="node()"/>
</xsl:variable>
<xsl:apply-templates mode="pass2"
select="ext:node-set($vrtfPass1)/node()"/>
</xsl:template>
<xsl:template match="/*">
<xsl:copy>
<xsl:copy-of select="@*"/>
<one/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|@*" mode="pass2">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="pass2"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*/one" mode="pass2" >
<xsl:call-template name="identity"/>
<two/>
</xsl:template>
</xsl:stylesheet>
当这种转变是在下面的XML文档应用:
<doc/>
有用结果(第一遍addds元件<one/>
作为第一个元素的子元素,那么第二个元素将添加另一个子元素,, immediately after the element
`在第一个元素中创建)产生:
<doc>
<one/>
<two/>
</doc>
有在FXSL非常合适的模板/函数来执行此:这是compose-flist
模板。它将初始数据参数和N个函数(模板)作为参数,并生成这些函数/模板的链接组合。
下面是从FXSL库试验例:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
xmlns:myFun1="f:myFun1"
xmlns:myFun2="f:myFun2"
xmlns:ext="http://exslt.org/common"
exclude-result-prefixes="xsl f ext myFun1 myFun2"
>
<xsl:import href="compose.xsl"/>
<xsl:import href="compose-flist.xsl"/>
<!-- to be applied on any xml source -->
<xsl:output method="text"/>
<myFun1:myFun1/>
<myFun2:myFun2/>
<xsl:template match="/">
<xsl:variable name="vFun1" select="document('')/*/myFun1:*[1]"/>
<xsl:variable name="vFun2" select="document('')/*/myFun2:*[1]"/>
Compose:
(*3).(*2) 3 =
<xsl:call-template name="compose">
<xsl:with-param name="pFun1" select="$vFun1"/>
<xsl:with-param name="pFun2" select="$vFun2"/>
<xsl:with-param name="pArg1" select="3"/>
</xsl:call-template>
<xsl:variable name="vrtfParam">
<xsl:copy-of select="$vFun1"/>
<xsl:copy-of select="$vFun2"/>
<xsl:copy-of select="$vFun1"/>
</xsl:variable>
Multi Compose:
(*3).(*2).(*3) 2 =
<xsl:call-template name="compose-flist">
<xsl:with-param name="pFunList" select="ext:node-set($vrtfParam)/*"/>
<xsl:with-param name="pArg1" select="2"/>
</xsl:call-template>
</xsl:template>
<xsl:template match="myFun1:*" mode="f:FXSL">
<xsl:param name="pArg1"/>
<xsl:value-of select="3 * $pArg1"/>
</xsl:template>
<xsl:template match="myFun2:*" mode="f:FXSL">
<xsl:param name="pArg1"/>
<xsl:value-of select="2 * $pArg1"/>
</xsl:template>
</xsl:stylesheet>
当这种转化是在任何XML文档(未使用)施加时,想要的,正确的结果产生:
Compose:
(*3).(*2) 3 =
18
Multi Compose:
(*3).(*2).(*3) 2 =
36
注意事项:在XSLT 2.0及更高版本中,不需要xxx:node-set()
扩展名,并且任何链ed变换可以包含在一个实际函数中。
+0
非常彻底。感谢您的答复! – jbeard4 2010-11-21 17:56:45
0
一种方法是使用http://www.w3.org/TR/xslt#modes模式,但是您需要将每个步骤转换为变量并使用节点集扩展功能才能将下一步应用于变量内容。
相关问题
- 1. 是否有一个技术术语用于转换数据的维度?
- 2. XSL转换 - 合并元素
- 3. 简单的XSL转换
- 4. 有没有任何工具或技术将phtoshop转换为HTML?
- 5. 是否有一个“转换器”,将CSS转换为IE兼容?
- 6. 是否有可能将Windows程序集转换为单声道?
- 7. XSL转换XML
- 8. xsl转换
- 9. XSL将SVG转换为VML
- 10. 将xml转换为xsl
- 11. 将数组转换成表
- 12. 在Seal中将Seq转换为管道
- 13. 是否有转换工具可以转换单个作业或多个作业?
- 14. 使用XSL单个XML文档转换成多个文档
- 15. XSL转换和XPath
- 16. 递归xsl转换
- 17. XSL转换和XPath
- 18. XSL转换日期
- 19. 用XSL转换XML
- 20. XSL转换注释
- 21. 结合2个XML文件转换成1使用XSL
- 22. 将ms-access前端转换为基于web的技术
- 23. 创建将xml转换为XHTML的XSL转换
- 24. 的xsl:将一个列表转换成2-d表
- 25. 有关从Golang []字节和字符串转换的技术
- 26. 是否有算法将数字组合转换为一个数字?
- 27. 将char数组转换为单个int?
- 28. XSL 1.0转换到合并节点
- 29. 转换单列成
- 30. parse5 SAXParser:管道转换为可读的流转换字符串
好问题,+1。请参阅我的答案,以获得广泛的解释以及提出的解决方案的两个示例。 – 2010-11-21 17:16:03