【问题标题】:Grouping like elements into separate groups将相似的元素分组到不同的组中
【发布时间】:2020-02-29 14:12:51
【问题描述】:

我有以下 XML:

<root>
  <node>
    <prop>a</prop>
    <amount>10</amount>
  </node>
  <node>
    <prop>a</prop>
    <amount>20</amount>
  </node>
  <node>
    <prop>b</prop>
    <amount>15</amount>
  </node>
  <node>
    <prop>b</prop>
    <amount>25</amount>
  </node>
  <node>
    <prop>a</prop>
    <amount>17</amount>
  </node>
</root>

我想根据它们的prop 将节点分组为段:

<root>
  <segment>
    <prop>a</prop>
    <node>
      <amount>10</amount>
    </node>
    <node>
      <amount>20</amount>
    </node>
  </segment>
  <segment>
    <prop>b</prop>
    <node>
      <amount>15</amount>
    </node>
    <node>
      <amount>25</amount>
    </node>
  </segment>
  <segment>
    <prop>a</prop>
    <node>
      <amount>17</amount>
    </node>
  </segment>
</root>

但正如您所见,最后一个“a”节点必须放在另一个segment 中——这是因为三个“a”节点不连续。 当我尝试对它们进行分组时,所有“a”节点都会被放在一起。有没有办法按照示例中的说明对它们进行分组?

【问题讨论】:

    标签: xml xslt xpath grouping xslt-1.0


    【解决方案1】:

    XSLT 1.0

    中试试这个
        <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="1.0">
        <xsl:template match="node() | @*">
            <xsl:copy>
                <xsl:apply-templates select="node() | @*"/>
            </xsl:copy>
            </xsl:template>
    
        <xsl:output indent="yes"/>
    
        <xsl:template match="root">
            <xsl:copy>
                <xsl:for-each select="node[position() = 1 or prop != preceding-sibling::node[1]/prop]">
                    <segment>
                        <xsl:copy-of select="prop"/>
                        <xsl:variable name="prop" select="prop"/>
                        <xsl:call-template name="retrivenode">
                            <xsl:with-param name="currentnode" select="."/>
                            <xsl:with-param name="prop" select="$prop"/>
                        </xsl:call-template>
                    </segment>
                </xsl:for-each>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template name="retrivenode">
            <xsl:param name="currentnode"/>
            <xsl:param name="prop"/>
            <xsl:apply-templates select="$currentnode"/>
            <xsl:if test="$currentnode/following-sibling::node[1][prop = $prop]">
                <xsl:call-template name="retrivenode">
                    <xsl:with-param name="currentnode" select="$currentnode/following-sibling::node[1]"/>
                    <xsl:with-param name="prop" select="$prop"/>
                </xsl:call-template>
            </xsl:if>
        </xsl:template>
    
        <xsl:template match="node">
            <xsl:copy>
                <xsl:apply-templates select="*[not(local-name() = 'prop')]">
    
                </xsl:apply-templates>
            </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>
    

    请参阅 https://xsltfiddle.liberty-development.net/3NSTbfk 的转换

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-16
      相关资源
      最近更新 更多