将相似的元素分组到不同的组中
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>
处的转换
我有以下 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>
处的转换