我有一个定义了几个函数的XSL。
我想编写带有XSL函数名称(以及参数列表)的Java代码并运行该函数(当然,将参数绑定到函数的形式参数)。
到目前为止,我唯一的解决方案是使用运行所选功能的主模板动态生成XSL代码。这很尴尬。我正在寻找一种解决方案,让我直接通过Saxon API运行一个函数。
答案 0 :(得分:1)
XPath Visualizer执行此操作的方式(无论使用何种XSLT处理器)是将主XSL样式表作为XML文档加载,并使用必要的XPath表达式动态修改一个select
属性。
像这样:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="yourTrueMainStylesheetModule"/>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vResult" select="."/>
<xsl:template match="/">
<xsl:sequence select="$vResult"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
将上述样式表模块加载为XmlDocument。
问题:SelectNodes("/*/xsl:variable[@name='vResult']/@select")
使用您的DOM API将所选属性的值修改为所需属性,例如:my:foo(1,2,3)
。
使用已加载的(并动态修改的样式表。
我多年来一直使用XPath Visualizer 2(对于XSLT 2.0 - 未发布)作为FXSL函数的命令行解释器。我可以随意写:
f:fold(f:mult(), 1, 1 to 4)
并显示正确的结果:
24
以下是使用XPath Visualizer 2作为FXSL解释器的屏幕截图:
答案 1 :(得分:0)
你可能不能直接,但是你不能让主模板根据你的一个参数调用不同的模板,比如一个大的switch语句。
答案 2 :(得分:0)
有一个API为XQuery(s9api包中的XQueryEvaluator.callFunction())执行此操作,但没有任何可比的XSLT。它可能通过调用正确的低级内部方法序列来实现它,但您可能必须研究源代码才能使其工作。
答案 3 :(得分:0)
XSLT已经具有根据输入文档的内容运行不同指令的功能:模板。我相信如果你已经在运行XSLT,那么乱用Saxon的内部API太麻烦了,只需编译一次这个大型XSLT并重新使用它。
花点时间了解XSLT及其功能性,并使用正确的match
表达式将这些函数转换为模板。
我举一个例子。假设我们有两个输入XML:
<myxml>
<doctype>recipe</doctype>
<descr>Bread 'n jam sandwich</descr>
<var>jam</var>
<var>bread</var>
</myxml>
<myxml>
<doctype>shoppinglist</doctype>
<descr>Monday</descr>
<var>honey</var>
<var>butter</var>
<var>loaf of bread</var>
<var>jam</var>
</myxml>
现在假设我们想要使用正确的格式为这些XML生成HTML。第一个XML应生成带有“Recipe:”的HTML和一系列成分。第二个应该包含一个购物清单。
这是生成两者的XSLT:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:saxon="http://saxon.sf.net/"
exclude-result-prefixes="xs saxon">
<xsl:output method="html" indent="yes"/>
<!-- Generate basic html -->
<xsl:template match="/">
<html>
<body><xsl:apply-templates /></body>
</html>
</xsl:template>
<!-- Only call template doctype element, not for vars -->
<xsl:template match="myxml">
<xsl:apply-templates select="doctype"/>
</xsl:template>
<xsl:template match="doctype[.='shoppinglist']">
<h1>Shopping list for <xsl:value-of select="../descr"/></h1>
<span><b>Stuff to bring:</b></span>
<ul>
<xsl:for-each select="../var">
<li><xsl:value-of select="."/></li>
</xsl:for-each>
</ul>
</xsl:template>
<xsl:template match="doctype[.='recipe']">
<h1>Recipe: <xsl:value-of select="../descr"/></h1>
<span><b>Ingredients:</b></span>
<ul>
<xsl:for-each select="../var">
<li><xsl:value-of select="."/></li>
</xsl:for-each>
</ul>
</xsl:template>
</xsl:stylesheet>
现在查看最后一个模板的match
参数。在这种情况下,我根据元素的内容进行选择,但您可以使用您喜欢的任何XPath过滤器表达式(即根据XML参数进行选择)。