2011-10-21 44 views
3

需要從系統A變換該請求到FINT到系統B的請求XSLT 1.0 - 分組XML元素

假設我有,看起來像這樣從系統A的XML文檔:

<root> 
<Bundle> 
    <authors> 
     <author> 
      <authorID>100</authorID> 
      <authorName>Kathisiera</authorName> 
     </author> 
     <author> 
      <authorID>200</authorID> 
      <authorName>Bates</authorName> 
     </author> 
     <author> 
      <authorID>300</authorID> 
      <authorName>Gavin King</authorName> 
     </author> 
    </authors> 
    <books> 
     <book> 
      <bookOrderID>1111</bookOrderID> 
      <bookName>Head First Java</bookName> 
      <bookRefID>100</bookRefID> 
     </book> 
     <book> 
      <bookOrderID>5555</bookOrderID> 
      <bookName>Head First Servlets</bookName> 
      <bookRefID>200</bookRefID> 
     </book> 
     <book> 
      <bookOrderID>1111</bookOrderID> 
      <bookName>Hibernate In Action</bookName> 
      <bookRefID>300</bookRefID> 
     </book> 
    </books> 
</Bundle> 

我必須適應該請求到系統B的請求結構:

<root> 
<Bundle> 
    <authors> 
     <author> 
      <authorID>100</authorID> 
      <authorName>Kathisiera</authorName> 
     </author> 
     <author> 
      <authorID>300</authorID> 
      <authorName>Gavin King</authorName> 
     </author> 
    </authors> 
    <books> 
     <book> 
      <bookOrderID>1111</bookOrderID> 
      <bookName>Head First Java</bookName> 
      <bookRefID>100</bookRefID> 
     </book> 
     <book> 
      <bookOrderID>1111</bookOrderID> 
      <bookName>Hibernate In Action</bookName> 
      <bookRefID>300</bookRefID> 
     </book> 
    </books> 
</Bundle> 
<Bundle> 
    <authors> 
     <author> 
      <authorID>200</authorID> 
      <authorName>Bates</authorName> 
     </author> 
    </authors> 
    <books> 
     <book> 
      <bookOrderID>5555</bookOrderID> 
      <bookName>Head First Servlets</bookName> 
      <bookRefID>200</bookRefID> 
     </book> 
    </books> 
</Bundle> 

首先,我必須根據bookOrderID根據Bundlebook。然後通過比較bookRefIDauthorIDauthorBundle

我試過使用key() generate-id()函數xslt。但無法獲得預期的結果。

請幫我解決問題。

回答

1
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="xml" indent="yes"/> 

    <xsl:key name="k" match="book" use="bookOrderID"/> 
    <xsl:key name="a" match="author" use="authorID"/> 

    <xsl:template match="/root"> 
     <xsl:copy> 
      <xsl:apply-templates select="//books"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="books"> 

     <xsl:apply-templates select="book[generate-id(.) = generate-id(key('k', bookOrderID))]"/> 

    </xsl:template> 

    <xsl:template match="book"> 
     <Bundle> 
      <authors> 
       <xsl:apply-templates select="key('a', key('k', bookOrderID)/bookRefID)"/> 
      </authors> 

      <books> 
       <xsl:copy-of select="key('k', bookOrderID)"/> 
      </books> 
     </Bundle> 
    </xsl:template> 

    <xsl:template match="@* | node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* | node()"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

輸入:

<root> 
    <Bundle> 
     <authors> 
      <author> 
       <authorID>100</authorID> 
       <authorName>Kathisiera</authorName> 
      </author> 
      <author> 
       <authorID>200</authorID> 
       <authorName>Bates</authorName> 
      </author> 
      <author> 
       <authorID>300</authorID> 
       <authorName>Gavin King</authorName> 
      </author> 
     </authors> 
     <books> 
      <book> 
       <bookOrderID>1111</bookOrderID> 
       <bookName>Head First Java</bookName> 
       <bookRefID>100</bookRefID> 
      </book> 
      <book> 
       <bookOrderID>5555</bookOrderID> 
       <bookName>Head First Servlets</bookName> 
       <bookRefID>200</bookRefID> 
      </book> 
      <book> 
       <bookOrderID>1111</bookOrderID> 
       <bookName>Hibernate In Action</bookName> 
       <bookRefID>300</bookRefID> 
      </book> 
     </books> 
    </Bundle> 
</root> 

輸出:

<root> 
    <Bundle> 
     <authors> 
      <author> 
       <authorID>100</authorID> 
       <authorName>Kathisiera</authorName> 
      </author> 
      <author> 
       <authorID>300</authorID> 
       <authorName>Gavin King</authorName> 
      </author> 
     </authors> 
     <books> 
      <book> 
       <bookOrderID>1111</bookOrderID> 
       <bookName>Head First Java</bookName> 
       <bookRefID>100</bookRefID> 
      </book> 
      <book> 
       <bookOrderID>1111</bookOrderID> 
       <bookName>Hibernate In Action</bookName> 
       <bookRefID>300</bookRefID> 
      </book> 
     </books> 
    </Bundle> 
    <Bundle> 
     <authors> 
      <author> 
       <authorID>200</authorID> 
       <authorName>Bates</authorName> 
      </author> 
     </authors> 
     <books> 
      <book> 
       <bookOrderID>5555</bookOrderID> 
       <bookName>Head First Servlets</bookName> 
       <bookRefID>200</bookRefID> 
      </book> 
     </books> 
    </Bundle> 
</root> 
+0

+1與我的解決方案基本相同。 :) – Tomalak

0

下面是做到這一點的一種方法:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 

    <xsl:key name="kBook" match="book" use="bookOrderID" /> 

    <xsl:template match="node() | @*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node() | @*" /> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="root"> 
    <xsl:apply-templates mode="bundle" select="Bundle/books/book[ 
     generate-id() 
     = 
     generate-id(key('kBook', bookOrderID)[1]) 
    ]" /> 
    </xsl:template> 

    <xsl:template match="book" mode="bundle"> 
    <xsl:variable name="bookGroup" select="key('kBook', bookOrderID)" /> 
    <Bundle> 
     <authors> 
     <xsl:copy-of select="//author[authorID = $bookGroup/bookRefID]" /> 
     </authors> 
     <books> 
     <xsl:copy-of select="$bookGroup" /> 
     </books> 
    </Bundle> 
    </xsl:template> 
</xsl:stylesheet> 

這組書通過他們的bookOrderID使用<xsl:key>

之後,它使用了=運營商的屬性來找到所有相關的autors:本=操作所有節點上相互兩側進行比較。把它看作是節點集的一種「內連接」。這樣你就可以用簡單的<xsl:copy-of>複製正確的節點。