基于子节点依赖的XML分组

时间:2017-01-24 15:45:15

标签: xml xslt-2.0

我尝试了for-each-group循环但是没有为我做这个技巧。基本上我有以下xml:

<Root>
    <Row>
        <CODE>A001</CODE>
        <LANG>EN</LANG>
        <DESCR>Car</DESCR>
    </Row>
    <Row>
        <CODE>A001</CODE>
        <LANG>FR</LANG>
        <DESCR>Voiture</DESCR>
    </Row>
    <Row>
        <CODE>A001</CODE>
        <LANG>NL</LANG>
        <DESCR>Auto</DESCR>
    </Row>
    <Row>
        <CODE>A002</CODE>
        <LANG>EN</LANG>
        <DESCR>Bicycle</DESCR>
    </Row>
    <Row>
        <CODE>A002</CODE>
        <LANG>FR</LANG>
        <DESCR>Velo</DESCR>
    </Row>
    <Row>
        <CODE>A002</CODE>
        <LANG>NL</LANG>
        <DESCR>Fiets</DESCR>
    </Row>
</Root>

我希望获得以下输出:

<Root>
	<Row>
		<CODE>A001</CODE>
		<DESCR Lang="EN">Car</DESCR>
		<DESCR Lang="FR">Voiture</DESCR>
		<DESCR Lang="NL">Auto</DESCR>
	</Row>
	<Row>
		<CODE>A002</CODE>
		<DESCR Lang="EN">Bicycle</DESCR>
		<DESCR Lang="FR">Velo</DESCR>
		<DESCR Lang="NL">Fiets</DESCR>
	</Row>
</Root>

感谢改变这种方式的帮助。感谢。

1 个答案:

答案 0 :(得分:1)

由于问题被标记为XSLT 2.0,因此这是一个XSLT 2.0解决方案:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
    <xsl:template match="/">
        <xsl:element name="Root">
            <xsl:for-each-group select="Root/Row" group-by="CODE">
                <xsl:element name="Row">
                    <xsl:copy-of select="CODE"/>
                    <xsl:for-each select="current-group()">
                        <xsl:element name="DESCR">
                            <xsl:attribute name = "Lang">
                                <xsl:value-of select="LANG"/>
                            </xsl:attribute>
                            <xsl:value-of select="DESCR"/>
                        </xsl:element>
                    </xsl:for-each>
                </xsl:element>
            </xsl:for-each-group>
        </xsl:element>
    </xsl:template>
</xsl:transform>

生成所需的输出:

<Root>
   <Row>
      <CODE>A001</CODE>
      <DESCR Lang="EN">Car</DESCR>
      <DESCR Lang="FR">Voiture</DESCR>
      <DESCR Lang="NL">Auto</DESCR>
   </Row>
   <Row>
      <CODE>A002</CODE>
      <DESCR Lang="EN">Bicycle</DESCR>
      <DESCR Lang="FR">Velo</DESCR>
      <DESCR Lang="NL">Fiets</DESCR>
   </Row>
</Root>

XSLT 1.0

使用Muenchian分组将Row<CODE>节点的值相同组合在一起。

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
    <xsl:key name="codes" match="Root/Row" use="CODE"/>
    <xsl:template match="/">
        <xsl:element name="Root">
            <xsl:for-each select="Root/Row[generate-id(.) = generate-id(key('codes',CODE)[1])]">
                <xsl:element name="Row">
                    <xsl:copy-of select="CODE"/>
                    <xsl:for-each select="key('codes',CODE)">
                        <xsl:element name="DESCR">
                            <xsl:attribute name = "Lang">
                                <xsl:value-of select="LANG"/>
                            </xsl:attribute>
                            <xsl:value-of select="DESCR"/>
                        </xsl:element>
                    </xsl:for-each>
                </xsl:element>
            </xsl:for-each>
        </xsl:element>
    </xsl:template>
</xsl:transform>