繁体   English   中英

将相似的元素分组到不同的组中

[英]Grouping like elements into separate groups

我有以下 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”节点都被扔在一起。 有没有办法按照示例中的说明对它们进行分组?

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 上的转换

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM