XSLT:根据给定列表组合节点

时间:2016-02-28 20:32:32

标签: xml xslt

知道如何使用XSLT实现所需的输出吗?

源XML:

<results>
   <pageFunctionResult>
      <id>46555</id>
      <name>URC 90 S</name>
      <quantity>5+</quantity>
   </pageFunctionResult>
   <pageFunctionResult>
      <id>46556</id>
      <name>URC 90 M</name>
      <quantity>5+</quantity>
   </pageFunctionResult>
   <pageFunctionResult>
      <id>46557</id>
      <name>URC 90 L</name>
      <quantity>10+</quantity>
   </pageFunctionResult>
   <pageFunctionResult>
      <id>96555</id>
      <name>NICE</name>
      <quantity>5+</quantity>
   </pageFunctionResult>
   <pageFunctionResult>
      <id>26555</id>
      <name>NEW L</name>
      <quantity>5+</quantity>
   </pageFunctionResult>
   <pageFunctionResult>
      <id>26552</id>
      <name>NEW XXL</name>
      <quantity>5+</quantity>
   </pageFunctionResult>
</results>

我需要以某种方式组合这些基于给定列表的元素(它可以是xsl:variable),例如: "URC 90", "NEW"

让我向您展示示例输出的外观:

<results>
   <pageFunctionResult>
      <name>URC 90</name>
      <variantname>URC 90 S</variantname>
      <id>46555</id>
      <quantity>5+</quantity>
      <variant id="1">
         <id>46556</id>
         <name>URC 90 M</name>
         <quantity>5+</quantity>
      </variant>
      <variant id="2">
         <id>46557</id>
         <name>URC 90 L</name>
         <quantity>10+</quantity>
      </variant>
   </pageFunctionResult>
   <pageFunctionResult>
      <id>96555</id>
      <name>NICE</name>
      <quantity>5+</quantity>
   </pageFunctionResult>
   <pageFunctionResult>
      <name>NEW</name>
      <variantname>NEW L</variantname>
      <id>46555</id>
      <quantity>5+</quantity>
      <variant id="1">
         <id>26552</id>
         <name>NEW XXL</name>
         <quantity>5+</quantity>
      </variant>
   </pageFunctionResult>   
</results>

在源XML中,我们有一个不在给定列表中的项目:NICE。应该按原样复制这些节点(无需修改)。

您认为如果我们知道<name>元素的一部分,有可能实现此输出吗?

1 个答案:

答案 0 :(得分:1)

这是一个XSLT 2.0示例,可以根据需要实现分组:

<?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="'NEW', 'URC 90'"/>

    <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(name, $values)">
                <xsl:choose>
                    <xsl:when test="name ne current-grouping-key()">
                            <xsl:copy>
                                <name>
                                    <xsl:value-of select="current-grouping-key()"/>
                                </name>
                                <variantname>
                                    <xsl:value-of select="name"/>
                                </variantname>
                                <xsl:copy-of select="id, quantity"/>
                                <xsl:apply-templates select="current-group() except ."/>
                            </xsl:copy>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:copy-of select="current-group()"/>
                    </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>

http://xsltransform.net/6r5Gh3R/1在线。