2016-02-28 3 views
0

Любая идея, как добиться желаемого результата с помощью 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>?

+0

Вы используете XSLT 2.0? –

+0

Да, версия XSLT не имеет значения. Я использую процессор SAXON. – Adrian

ответ

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> 

Online на http://xsltransform.net/6r5Gh3R/1.

+0

Это супербибль! Осталось еще один вопрос: можем ли мы добавить '' ' MAINPRODUCT' '' после страницыФункцияResult (но не в варианте)? Я хочу отметить корневые элементы. – Adrian

+0

Думаю, что я понял. Отзыв приветствуется: http://xsltransform.net/6r5Gh3R/4 – Adrian

+0

Я думаю, вы добавили один подход, чтобы добавить этот элемент 'position', вместо' for-each select = "current-group()" 'you вы также можете использовать обработку стиля push с помощью 'apply-templates select =" current-group() "', в этом случае с отдельным 'mode', как это сделано в http://xsltransform.net/6r5Gh3R/5 , –

Смежные вопросы