我有以下源数据:
<DATA>
<ITEM>
<ID>28</ID>
<BRAND>TGR</BRAND>
<ACC_NO>143080</ACC_NO>
<ACC_DESCR>account description</ACC_DESCR>
</ITEM>
<ITEM>
<ID>28</ID>
<BRAND>TGR</BRAND>
<ACC_NO>272180</ACC_NO>
<ACC_DESCR>account description</ACC_DESCR>
</ITEM>
<ITEM>
<ID>32</ID>
<BRAND>TGR</BRAND>
<ACC_NO>159880</ACC_NO>
<ACC_DESCR>account description</ACC_DESCR>
</ITEM>
</DATA>
我想转变成:
<DATA>
<ITEM>
<ID>28</ID>
<BRAND>TGR</BRAND>
<ACCOUNTS>
<ACCOUNT>
<ACC_NO>143080</ACC_NO>
<ACC_DESCR>account description</ACC_DESCR>
<ACCOUNT>
<ACCOUNT>
<ACC_NO>272180</ACC_NO>
<ACC_DESCR>account description</ACC_DESCR>
<ACCOUNT>
<ACCOUNTS>
</ITEM>
<ITEM>
<ID>32</ID>
<BRAND>TGR</BRAND>
<ACCOUNTS>
<ACCOUNT>
<ACC_NO>159880</ACC_NO>
<ACC_DESCR>account description</ACC_DESCR>
<ACCOUNT>
<ACCOUNTS>
</ITEM>
</DATA>
应用以下转换:
<xsl:template match="/">
<xsl:for-each select="/DATA/ITEM">
<ITEM>
<ID>
<xsl:value-of select="ID"/>
</ID>
<BRAND>
<xsl:value-of select="BRAND"/>
<BRAND>
<ACCOUNTS>
<ACCOUNT>
<AccountNumber>
<xsl:value-of select="ACC_NO"/>
<AccountNumber>
<AccountDescription>
<xsl:value-of select="ACC_DESCR"/>
<AccountDescription>
</ACCOUNT>
</ACCOUNTS>
</ITEM>
</xsl:for-each>
</xsl:template>
我将在ITEM中获得ACCOUNTS列表,但仍然没有将ITEM与相同的ID合并。基本上我总是会得到一个带有单个元素的集合,而不是所有相同ID的帐户。
有任何建议我该如何做并产生所需的输出?
由于
答案 0 :(得分:1)
在XSLT 2.0中,您只需将for-each
替换为for-each-group
,然后添加内部for-each
即可为每个组成员创建一个ACCOUNT
:
<xsl:template match="/">
<xsl:for-each-group select="/DATA/ITEM" group-by="ID">
<ITEM>
<ID>
<xsl:value-of select="ID"/>
</ID>
<BRAND>
<xsl:value-of select="BRAND"/>
<BRAND>
<ACCOUNTS>
<xsl:for-each select="current-group()">
<ACCOUNT>
<AccountNumber>
<xsl:value-of select="ACC_NO"/>
<AccountNumber>
<AccountDescription>
<xsl:value-of select="ACC_DESCR"/>
<AccountDescription>
</ACCOUNT>
</xsl:for-each>
</ACCOUNTS>
</ITEM>
</xsl:for-each-group>
</xsl:template>
在1.0中,最有效的方法是称为 Muenchian分组的技术 - 定义密钥给出分组标准,然后使用generate-id
的技巧只提取给定ID的第一个实例作为整个组的代理。
<xsl:key name="itemById" match="ITEM" use="ID" />
<xsl:template match="/">
<xsl:for-each select="/DATA/ITEM[
generate-id() = generate-id(key('itemById', ID)[1])]">
<ITEM>
<ID>
<xsl:value-of select="ID"/>
</ID>
<BRAND>
<xsl:value-of select="BRAND"/>
<BRAND>
<ACCOUNTS>
<xsl:for-each select="key('itemById', ID)">
<ACCOUNT>
<AccountNumber>
<xsl:value-of select="ACC_NO"/>
<AccountNumber>
<AccountDescription>
<xsl:value-of select="ACC_DESCR"/>
<AccountDescription>
</ACCOUNT>
</xsl:for-each>
</ACCOUNTS>
</ITEM>
</xsl:for-each>
</xsl:template>
key('itemById', ID)[1]
为您提供第一个ITEM
元素,其值与我们正在测试的当前值相同ID
,然后比较两者的generate-id
值允许您确定它们是否是同一个节点。
(就个人而言,我会使用模板而不是for-each
来解决问题,但原则仍然相同)