我有以下XSLT,它通过对给定数组上的键进行分组来格式化输出:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs mf">
<xsl:param name="values" select="'Sniper 50 Red', 'Xiper 10 Red'"/>
<xsl:output indent="yes"/>
<xsl:function name="mf:match" as="xs:string">
<xsl:param name="input" as="xs:string"/>
<xsl:param name="values" as="xs:string*"/>
<xsl:sequence
select="if ($values[matches($input, concat('^', .))])
then $values[matches($input, concat('^', .))]
else $input"/>
</xsl:function>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="results">
<xsl:copy>
<xsl:for-each-group select="pageFunctionResult" group-by="mf:match(product_name, $values)">
<xsl:choose>
<xsl:when test="product_name ne current-grouping-key()">
<xsl:copy>
<position>MAINPRODUCT</position>
<variantname>
<xsl:value-of select="product_name"/>
</variantname>
<product_namea>
<xsl:value-of select="current-grouping-key()"/>
</product_namea>
<xsl:copy-of select="category, product_id, quantity, manufacturer,image"/>
<xsl:apply-templates select="current-group() except ."/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="current-group()">
<xsl:copy>
<position>MAINPRODUCT</position>
<variantname>
<xsl:value-of select="current-grouping-key()"/>
</variantname>
<xsl:apply-templates select="*"/>
</xsl:copy>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="pageFunctionResult">
<variant id="{position()}">
<xsl:apply-templates/>
</variant>
</xsl:template>
</xsl:transform>
在这里,您可以看到it in action。它工作得很好,但我现在的名字中带有括号的键:
<xsl:param name="values" select="'Sniper 50 Red (26)', 'Xiper 10 Red (27)'"/>
...这显然会使代码失效,因为括号在正则表达式中保留。所以括号应该被转义。我得到了使用functx:escape-for-regex的提示,但我无法将其实现到代码中。
答案 0 :(得分:1)
此示例显示如何使用functx
函数:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
xmlns:functx="http://www.functx.com"
exclude-result-prefixes="xs mf functx">
<xsl:param name="values" select="'Sniper 50 Red (26)', 'Xiper 10 Red (27)'"/>
<xsl:output indent="yes"/>
<xsl:function name="functx:escape-for-regex" as="xs:string"
>
<xsl:param name="arg" as="xs:string?"/>
<xsl:sequence select="
replace($arg,
'(\.|\[|\]|\\|\||\-|\^|\$|\?|\*|\+|\{|\}|\(|\))','\\$1')
"/>
</xsl:function>
<xsl:function name="mf:match" as="xs:string">
<xsl:param name="input" as="xs:string"/>
<xsl:param name="values" as="xs:string*"/>
<xsl:sequence
select="if ($values[matches($input, concat('^', functx:escape-for-regex(.)))])
then $values[matches($input, concat('^', functx:escape-for-regex(.)))]
else $input"/>
</xsl:function>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="results">
<xsl:copy>
<xsl:for-each-group select="pageFunctionResult" group-by="mf:match(product_name, $values)">
<xsl:choose>
<xsl:when test="product_name ne current-grouping-key()">
<xsl:copy>
<position>MAINPRODUCT</position>
<variantname>
<xsl:value-of select="product_name"/>
</variantname>
<product_namea>
<xsl:value-of select="current-grouping-key()"/>
</product_namea>
<xsl:copy-of select="category, product_id, quantity, manufacturer,image"/>
<xsl:apply-templates select="current-group() except ."/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="current-group()">
<xsl:copy>
<position>MAINPRODUCT</position>
<variantname>
<xsl:value-of select="current-grouping-key()"/>
</variantname>
<xsl:apply-templates select="*"/>
</xsl:copy>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="pageFunctionResult">
<variant id="{position()}">
<xsl:apply-templates/>
</variant>
</xsl:template>
</xsl:transform>