如何使用XSLT将以下两个XML中的第一个转换为第二个?
这样做的困难在于它并不是一个线性过程,因为第一个XML按日期对博客的评论进行分组,而第二个XML按用户对评论进行分组。
输入XML:
<blog>
<block>
<day>2011-11-20</day>
<data>
<comment>bla bla bla</comment>
<ops>
<user>357098</user>
<ops>
</data>
</block>
<block>
<day>2011-11-21</day>
<data>
<comment>blu blu blu</comment>
<ops>
<user>357098</user>
<ops>
</data>
<data>
<comment>bum</comment>
<ops>
<user>11111</user>
<ops>
</data>
</block>
</blog>
我必须在输出中得到这个:
<blog>
<user id="357098">
<list>
<comment>
<text>bla bla bla</text>
<date>2011-11-20</date>
</comment>
<comment>
<text>blu blu blu</text>
<date>2011-11-21</date>
</comment>
</list>
</user>
<user id="11111">
<list>
<comment>
<text>bum</text>
<date>2011-11-21</date>
</comment>
</list>
</user>
</blog>
答案 0 :(得分:1)
这是一个典型的分组问题,这是一个XSLT 1.0解决方案:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="kUser" match="data" use="ops/user" />
<xsl:template match="/*">
<xsl:copy>
<xsl:apply-templates select="block/data[generate-id() =
generate-id(key('kUser', ops/user)[1])]" />
</xsl:copy>
</xsl:template>
<xsl:template match="data">
<user id="{ops/user}">
<list>
<xsl:apply-templates select="key('kUser', ops/user)/comment" />
</list>
</user>
</xsl:template>
<xsl:template match="comment">
<comment>
<text>
<xsl:value-of select="." />
</text>
<date>
<xsl:value-of select="../../day" />
</date>
</comment>
</xsl:template>
</xsl:stylesheet>
在样本输入上运行时,结果为:
<blog>
<user id="357098">
<list>
<comment>
<text>bla bla bla</text>
<date>2011-11-20</date>
</comment>
<comment>
<text>blu blu blu</text>
<date>2011-11-21</date>
</comment>
</list>
</user>
<user id="11111">
<list>
<comment>
<text>bum</text>
<date>2011-11-21</date>
</comment>
</list>
</user>
</blog>