XSL由具有多个相似未知值的多个相似兄弟节点对节点进行分组

时间:2016-04-06 09:33:08

标签: xml xslt xpath xslt-1.0

好的我正在尝试构建一个表,但我没有正确地执行此操作,我没有XSL示例,因为我尝试的任何内容都接近我需要的内容。 (我尝试过使用xsl:apply-templates循环,即使是模式,甚至xsl:for-each和key(),但无法获得正确的过滤器。

以下是我将使用的XML示例。 (我使用的真正的xml比下面这个更复杂)

<report>
 <item>
  <vertical>
   <component>
    <partname>Left Side</partname>
    <parttype>Side</parttype>
    <partlocation>Outside</partlocation>
    <material>Wood</material>
    <thickness>20mm</thickness>
    <colour>White</colour>
   </component>
  </vertical>
  <vertical>
   <component>
    <partname>Right Side</partname>
    <parttype>Side</parttype>
    <partlocation>Outside</partlocation>
    <material>Wood</material>
    <thickness>20mm</thickness>
    <colour>White</colour>
   </component>
  </vertical>
  <vertical>
   <component>
    <partname>Back</partname>
    <parttype>Back</parttype>
    <partlocation>Inside</partlocation>
    <material>Plastic</material>
    <thickness>3mm</thickness>
    <colour>Black</colour>
   </component>
  </vertical>
 </item>
</report>

所以我想要做的任务是,每个<item>我需要开始制作一个表,在该表中我需要评估每个<component>以找出有多少具有相同的<material><thickness><colour>。 然后我需要列出材料名称和详细信息。 接下来,我需要具有相同<components><parttypes><partlocation>相同的<material><thickness>的所有<colour>来展示每个人的<partname>连续。 没有固定数量的材料我可以期待,有一次我可能得到1,另一次我可以得到3.而且我不会总是知道节点将包含什么值。 同样在每个<item>我可以有1-3个不同的<parttype><partlocation>(虽然它们成对工作 - 我知道这些节点的值是什么)

这是一个格式化完成的示例,给出了上面非常简单的代码...

Wood, 20mm, White
Left Side
Right Side

Plastic, 3mm, Black
Back

这个问题很相似,但并不完全...... xsl grouping of repetitive nodes by xml element in xslt1

1 个答案:

答案 0 :(得分:1)

您可以尝试使用此基于密钥的解决方案作为第一个想法:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="text" />
    <!-- Define keys -->
    <xsl:key name="kmaterial" match="component" 
             use="concat (generate-id(../..), '|', material, '|', thickness, '|', colour)"/>
    <xsl:template match="text()" />
    <xsl:template match="item">
        <xsl:for-each 
               select="vertical/component[
                    generate-id(.) = 
                    generate-id(key('kmaterial',   concat (generate-id(../..), '|', material, '|', thickness, '|', colour) )[1])  ]">

            <xsl:variable name="this" select="."/>
            <xsl:value-of select="material"/>, <xsl:value-of select="thickness"/> , <xsl:value-of select="colour"/>
            <xsl:text>&#10;</xsl:text>
            <xsl:for-each
                         select="key('kmaterial',   concat (generate-id(../..), '|', $this/material, '|', $this/thickness, '|', $this/colour) )" >
                <xsl:value-of select="partname"/>
                <xsl:text>&#10;</xsl:text>
            </xsl:for-each>

        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

使用以下输出:

Wood, 20mm , White
Left Side
Right Side
Plastic, 3mm , Black
Back