簡體   English   中英

XSLT-將節點合並到集合中

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM