问题
Below is the XML and I am looking for output as below
Input XML (xml version="1.0")
<dynamic>
<rpc xmlns="http://namespace/example" >
<route>
<table>
<tablename>employee</tablename>
<count>20</count>
</table>
<table>
<tablename>employee</tablename>
<count> 21</count>
<rt> 1</rt>
<rt> 2</rt>
<rt> 3</rt>
<rt> 4</rt>
</table>
<table>
<tablename>dept</tablename>
<count>20</count>
<rt> a</rt>
<rt> b</rt>
<rt> c</rt>
</table>
<table>
<tablename>dept</tablename>
<count>44</count>
<rt> d</rt>
<rt> e</rt>
<rt> g</rt>
</table>
</route>
</rpc>
</dynamic>
Please note, only the first <count>
value needs to be selected
Output XML
<dynamic>
<rpc xmlns="http://namespace/example">
<route>
<table>
<tablename>employee</tablename>
<count>20</count>
<rt> 1</rt>
<rt> 2</rt>
<rt> 3</rt>
<rt> 4</rt>
</table>
<table>
<tablename>dept</tablename>
<count>20</count>
<rt> a</rt>
<rt> b</rt>
<rt> c</rt>
<rt> d</rt>
<rt> e</rt>
<rt> g</rt>
</table>
</route>
</rpc>
</dynamic>
回答1:
One option using muenchian grouping...
Edited to handle default namespace.
XML
<dynamic>
<rpc xmlns="http://namespace/example" >
<route>
<table>
<tablename>employee</tablename>
<count>20</count>
</table>
<table>
<tablename>employee</tablename>
<count> 21</count>
<rt> 1</rt>
<rt> 2</rt>
<rt> 3</rt>
<rt> 4</rt>
</table>
<table>
<tablename>dept</tablename>
<count>20</count>
<rt> a</rt>
<rt> b</rt>
<rt> c</rt>
</table>
<table>
<tablename>dept</tablename>
<count>44</count>
<rt> d</rt>
<rt> e</rt>
<rt> g</rt>
</table>
</route>
</rpc>
</dynamic>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:rpc="http://namespace/example">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<!--Create a key matching "table" using "tablename" as the key.-->
<xsl:key name="table-by-name" match="rpc:table" use="rpc:tablename"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="rpc:route">
<xsl:copy>
<!--Iterate over the first "table" for each key ("tablename").
The context is now "table".-->
<xsl:for-each
select="rpc:table[count(.|key('table-by-name',rpc:tablename)[1])=1]">
<xsl:copy>
<!--apply-templates to the "tablename" and "count" elements.
Also apply-templates to "rt" children of items with a key
that matches the current "tablename".-->
<xsl:apply-templates
select="rpc:tablename|rpc:count|key('table-by-name',rpc:tablename)/rpc:rt"/>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Output
<dynamic>
<rpc xmlns="http://namespace/example">
<route>
<table>
<tablename>employee</tablename>
<count>20</count>
<rt> 1</rt>
<rt> 2</rt>
<rt> 3</rt>
<rt> 4</rt>
</table>
<table>
<tablename>dept</tablename>
<count>20</count>
<rt> a</rt>
<rt> b</rt>
<rt> c</rt>
<rt> d</rt>
<rt> e</rt>
<rt> g</rt>
</table>
</route>
</rpc>
</dynamic>
来源:https://stackoverflow.com/questions/47040094/xslt-xml-getting-first-occurrence-and-merging-the-tags