如何在 xslt 2.0 中将 flat xml 分组为 2 个级别
How to group flat xml into 2 levels in xslt 2.0
我有一个几乎平坦的 xml,其中有几个条目具有与标题相关的信息,这些信息将显示在条目的元数据之前。这些标题可以分为两级,第二级是可选的。请提出实现该目标的方法。
输入xml:
<world>
<country>
<name>USA</name>
<code>001</code>
<category type="developed" scheme="level1"/>
<category type="rich" scheme="level2"/>
</country>
<country>
<name>UK</name>
<code>044</code>
<category type="developed" scheme="level1"/>
<category type="rich" scheme="level2"/>
</country>
<country>
<name>LATVIA</name>
<code>371</code>
<category type="developed" scheme="level1"/>
</country>
<country>
<name>BHUTAN</name>
<code>975</code>
<category type="developing" scheme="level1"/>
</country>
</world>
期望的输出:
<world>
<developed>
<rich>
<country>
<name>USA</name>
<code>001</code>
</country>
<country>
<name>UK</name>
<code>044</code>
</country>
</rich>
<country>
<name>LATVIA</name>
<code>371</code>
</country>
</developed>
<developing>
<country>
<name>BHUTAN</name>
<code>975</code>
</country>
</developing>
</world>
嵌套两个for-each-group
:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="world">
<xsl:copy>
<xsl:for-each-group select="country" group-by="category[@scheme = 'level1']/@type">
<xsl:element name="{current-grouping-key()}">
<xsl:for-each-group select="current-group()[category[@scheme = 'level2']]" group-by="category[@scheme = 'level2']/@type">
<xsl:element name="{current-grouping-key()}">
<xsl:apply-templates select="current-group()"/>
</xsl:element>
</xsl:for-each-group>
<xsl:apply-templates select="current-group()[not(category[@scheme = 'level2'])]"/>
</xsl:element>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="country">
<xsl:copy>
<xsl:copy-of select="* except category"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我有一个几乎平坦的 xml,其中有几个条目具有与标题相关的信息,这些信息将显示在条目的元数据之前。这些标题可以分为两级,第二级是可选的。请提出实现该目标的方法。
输入xml:
<world>
<country>
<name>USA</name>
<code>001</code>
<category type="developed" scheme="level1"/>
<category type="rich" scheme="level2"/>
</country>
<country>
<name>UK</name>
<code>044</code>
<category type="developed" scheme="level1"/>
<category type="rich" scheme="level2"/>
</country>
<country>
<name>LATVIA</name>
<code>371</code>
<category type="developed" scheme="level1"/>
</country>
<country>
<name>BHUTAN</name>
<code>975</code>
<category type="developing" scheme="level1"/>
</country>
</world>
期望的输出:
<world>
<developed>
<rich>
<country>
<name>USA</name>
<code>001</code>
</country>
<country>
<name>UK</name>
<code>044</code>
</country>
</rich>
<country>
<name>LATVIA</name>
<code>371</code>
</country>
</developed>
<developing>
<country>
<name>BHUTAN</name>
<code>975</code>
</country>
</developing>
</world>
嵌套两个for-each-group
:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="world">
<xsl:copy>
<xsl:for-each-group select="country" group-by="category[@scheme = 'level1']/@type">
<xsl:element name="{current-grouping-key()}">
<xsl:for-each-group select="current-group()[category[@scheme = 'level2']]" group-by="category[@scheme = 'level2']/@type">
<xsl:element name="{current-grouping-key()}">
<xsl:apply-templates select="current-group()"/>
</xsl:element>
</xsl:for-each-group>
<xsl:apply-templates select="current-group()[not(category[@scheme = 'level2'])]"/>
</xsl:element>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="country">
<xsl:copy>
<xsl:copy-of select="* except category"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>