Function 基于XSLT v2.0中的函数参数的每个函数的动态
我想创建一个通用XSLT 2.0函数,它可以对xml进行如下操作:Function 基于XSLT v2.0中的函数参数的每个函数的动态,function,xslt,dynamic,xslt-2.0,value-of,Function,Xslt,Dynamic,Xslt 2.0,Value Of,我想创建一个通用XSLT 2.0函数,它可以对xml进行如下操作: <?xml version="1.0"?> <foo xmlns:my="http://meohmy.org" xmlns:yours="http://meohmy2.org"> <yours:pet my:type="dog" my:color="red">Cindy</yours:pet> <yours:pet my:type="cat">Felix
<?xml version="1.0"?>
<foo xmlns:my="http://meohmy.org" xmlns:yours="http://meohmy2.org">
<yours:pet my:type="dog" my:color="red">Cindy</yours:pet>
<yours:pet my:type="cat">Felix</yours:pet>
<yours:pet my:type="cat" my:color="green">Pai Mei</yours:pet>
</foo>
my:doit('item',/foo/yours:/pet,@my:color)
info=red;;green
(其中第一个参数是标签,第二个参数是我要报告的节点集,第三个参数是我要为第二个参数的节点集中的每个节点输出的值,无论它是否有)
我希望它返回如下数据:
<?xml version="1.0"?>
<foo xmlns:my="http://meohmy.org" xmlns:yours="http://meohmy2.org">
<yours:pet my:type="dog" my:color="red">Cindy</yours:pet>
<yours:pet my:type="cat">Felix</yours:pet>
<yours:pet my:type="cat" my:color="green">Pai Mei</yours:pet>
</foo>
my:doit('item',/foo/yours:/pet,@my:color)
info=red;;green
请注意,我需要一个空占位符,对应于没有第三个参数的元素,并且顺序很重要
因为我在样式表中经常这样做(出于不同的原因,我做了几十次),所以函数似乎是一种自然的方式。这就是我到目前为止想到的
<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="http://meohmy.org"
xmlns:yours="http://meohmy2.org">
<xsl:template match="/">
<xsl:value-of select="my:doit('item',/foo/yours:pet,@my:color)"/>
</xsl:template>
<xsl:function name="my:doit" as="xs:string?">
<xsl:param name="item" as="xs:string"/>
<xsl:param name="value"/>
<xsl:param name="subvalue"/>
<xsl:if test="$value">
<xsl:value-of>
<xsl:value-of select="$item"/>
<xsl:text>=</xsl:text>
<xsl:for-each select="$value">
<xsl:value-of select="current()/$subvalue"/>
<xsl:if test="position() != last()">
<xsl:text>;</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:value-of>
</xsl:if>
</xsl:function>
</xsl:stylesheet>
这表明样式表中的
不正确。我离得很近,我能感觉到;>有什么建议吗
谢谢 试试这个样式表
<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="http://meohmy.org"
xmlns:yours="http://meohmy2.org">
<xsl:template match="/">
<xsl:value-of select="my:doit('item',/foo/yours:pet,'my:color')"/>
</xsl:template>
<xsl:function name="my:doit" as="xs:string?">
<xsl:param name="item" as="xs:string"/>
<xsl:param name="value"/>
<xsl:param name="subvalue"/>
<xsl:if test="$value">
<xsl:value-of>
<xsl:value-of select="$item"/>
<xsl:text>=</xsl:text>
<xsl:for-each select="$value">
<xsl:value-of select="current()/attribute()[name() = $subvalue]"/>
<xsl:if test="position() != last()">
<xsl:text>;</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:value-of>
</xsl:if>
</xsl:function>
</xsl:stylesheet>
在您的示例中,您认为您正在传递一个XPath表达式作为第三个参数,但事实并非如此——您正在传递它的值 在XPath3.0中,有一个干净的解决方案:可以将函数作为第三个参数传递。所以这个电话变成了
select="my:doit('item', /foo/yours:pet, function($e){$e/@my:color})"
并且实现变得更加简单
<xsl:function name="my:doit" as="xs:string?">
<xsl:param name="item" as="xs:string"/>
<xsl:param name="value" as="element()*/>
<xsl:param name="subvalue" as="function(element()) as xs:string?"/>
<xsl:if test="$value">
<xsl:value-of>
<xsl:value-of select="$item"/>
<xsl:text>=</xsl:text>
<xsl:value-of select="$value ! $subvalue(.)" separator=";"/>
</xsl:value-of>
</xsl:if>
</xsl:function>
是的,但我不认为它像OP想要的那样通用。它只允许将属性名作为第三个参数传递,而不是任意的XPath表达式。但我不确定是否有可能在xlts 2.0中按照OP的要求制作通用解决方案。所以我做了一些简化。当然,如果有更好的解决方案,我想学习如何去做,因为有时候它会很有用。是的,我想我已经到了XSLT2.0的极限了。谢谢你!谢谢我将升级到XPath3.0,但我还发现Saxon的动态函数可以实现这一点(不过这需要Saxon的PE或EE(付费)版本)。