我想采用一些XML文档并合并具有相同属性值的某些级别的所有节点。例如,如果我有这种形式的文件,
<xml>
<books id="X">
<book name="Story"/>
<book name="Tale"/>
</books>
<books id="X">
<book name="Folklore"/>
<book name="Magic"/>
</books>
<books id="Y">
<book name="Harry Potter"/>
<book name="LotR"/>
</books>
</xml>
那么我希望能够将其转换为以下文档:
<xml>
<books id="X">
<book name="Story"/>
<book name="Tale"/>
<book name="Folklore"/>
<book name="Magic"/>
</books>
<books id="Y">
<book name="Harry Potter"/>
<book name="LotR"/>
</books>
</xml>
如果可能的话,我非常想要多种解决方案。例如,一个使用XSLT,另一个使用其他语言。
你可以试试这个:
<xsl:template match="xml">
<xsl:for-each-group select="books" group-by="@id">
<xsl:copy>
<xsl:attribute name="id" select="current-grouping-key()"/>
<xsl:apply-templates select="current-group()/*"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="books[1][@id='X']">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
<xsl:apply-templates select="following-sibling::books[@id='X']/book"/>
</xsl:copy>
</xsl:template>
<xsl:template match="books[@id='X' and preceding-sibling::books[@id='X']]"/>
<xsl:template match="book">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
check it.