[英]XSLT - Merge nodes into collection
我有以下源數據:
<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列表,但仍不合並具有相同ID的ITEM。 基本上,我將始終獲得具有單個元素的集合,而不是具有相同ID的所有帳戶。
有什么建議我該怎么做並產生所需的輸出?
謝謝
在XSLT 2.0中,您只需用一個for-each-group
替換外部for-each
,然后添加一個內部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
來解決該問題for-each
但是原理保持不變)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.