【问题标题】:XSL Grouping nodes by multiple similar siblings with multiple similar unknown valuesXSL 通过具有多个相似未知值的多个相似同级对节点进行分组
【发布时间】:2016-04-06 09:33:08
【问题描述】:

好的,我正在尝试构建一个表,但我没有正确执行此操作,我没有 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>

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

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

Wood, 20mm, White
Left Side
Right Side

Plastic, 3mm, Black
Back

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

【问题讨论】:

    标签: xml xslt xpath xslt-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
    

    【讨论】:

    • 感谢 hr_117 的输入,我一直在我的实际文件中使用这个建议,看看我是否可以让它完成所需的工作,但我担心它可能只是任务的一半。
    • 要通过parttypespartlocation 进行分组(下一步),您需要有第二个密钥(例如kmaterialpart)。这应该与由'|', parttypes '|', partlocation 扩展的kmaterial 相同
    • 我终于对这个进行了非常仔细的研究,经过一番混合使其在我的实际项目中发挥作用,这个答案的第一阶段肯定解决了我的困境,我一直有Key() 的麻烦并试图更好地理解它。谢谢@hr_117
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-06
    • 1970-01-01
    • 2014-12-08
    • 1970-01-01
    • 2015-10-07
    • 1970-01-01
    相关资源
    最近更新 更多