2014-12-30 133 views
-2

我有一個從SQL表中生成的XML文件。我需要將XML轉換爲我需要的輸出XML。需要幫助來創建XSLT

輸入XML:

<rowset> 
<row> 
<aaa>123</aaa> 
<bbb>James</bbb> 
<ddd>Large</ddd> 
<eee>Black</eee> 
<ddd>456213</ddd> 
</row> 
<row> 
<aaa>123</aaa> 
<bbb>James</bbb> 
<ddd>Large</ddd> 
<eee>Blue</eee> 
<ddd>456213</ddd> 
</row> 
<row> 
<aaa>123</aaa> 
<bbb>James</bbb> 
<ddd>small</ddd> 
<eee>Black</eee> 
<ddd>456213</ddd> 
</row> 
<row> 
<aaa>123</aaa> 
<bbb>James</bbb> 
<ddd>small</ddd> 
<eee>blue</eee> 
<ddd>456213</ddd> 
</row> 
<row> 
<aaa>321</aaa> 
<bbb>William</bbb> 
<ddd>Large</ddd> 
<eee>White</eee> 
<ddd>555555</ddd> 
</row> 
<row> 
<aaa>321</aaa> 
<bbb>William</bbb> 
<ddd>Large</ddd> 
<eee>Yellow</eee> 
<ddd>555555</ddd> 
</row> 
<row> 
<aaa>321</aaa> 
<bbb>William</bbb> 
<ddd>small</ddd> 
<eee>White</eee> 
<ddd>555555</ddd> 
</row> 
<row> 
<aaa>321</aaa> 
<bbb>William</bbb> 
<ddd>small</ddd> 
<eee>Yellow</eee> 
<ddd>555555</ddd> 
</row> 
</rowset> 

輸出XML:

<?xml version="1.0" encoding="utf-8"?> 
<tXML xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user="urn:my-scripts"> 
<product product-id = "123"> 
    <Name>James</Name> 
    <Image> 
     <Image image-view-type = "Large" image-color = "Black"> 
     <Image image-view-type = "Large" image-color = "Blue"> 
     <Image image-view-type = "small" image-color = "Black"> 
     <Image image-view-type = "small" image-color = "Blue"> 
    </Image> 
    <DeptCode>456213</DeptCode> 
</product> 
<product product-id = "321"> 
    <Name>William</Name> 
    <Image> 
     <Image image-view-type = "Large" image-color = "White"> 
     <Image image-view-type = "Large" image-color = "Yellow"> 
     <Image image-view-type = "small" image-color = "White"> 
     <Image image-view-type = "small" image-color = "Yellow"> 
    </Image> 
    <DeptCode>555555</DeptCode> 
</product> 
</tXML> 

如何編寫XSLT這一點。 請注意產品很多。所以會有成千上萬的產品。

+0

您使用的是哪個版本的XSLT? –

回答

1

要對此XML進行排序,您可以使用Muenchian分組。下面的XSLT

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 
    <xsl:key name="prodId" match="row" use="aaa" /> 
    <xsl:template match="rowset"> 
    <xsl:for-each select="row[generate-id() = 
      generate-id(key('prodId', aaa)[1])]"> 
     <product product-id = "{aaa}"> 
     <Name><xsl:value-of select="bbb"/></Name> 
     <xsl:for-each select="key('prodId', aaa)"> 
      <Image> 
      <xsl:attribute name="image-view-type" select="ddd[1]"/> 
      <xsl:attribute name="image-color" select="eee"/> 
      </Image> 
     </xsl:for-each> 
     <DeptCode><xsl:value-of select="ddd[2]"/></DeptCode> 
     </product> 
    </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

當適用於您輸入XML產生輸出

<product product-id="123"> 
    <Name>James</Name> 
    <Image image-view-type="Large" image-color="Black"/> 
    <Image image-view-type="Large" image-color="Blue"/> 
    <Image image-view-type="small" image-color="Black"/> 
    <Image image-view-type="small" image-color="blue"/> 
    <DeptCode>456213</DeptCode> 
</product> 
<product product-id="321"> 
    <Name>William</Name> 
    <Image image-view-type="Large" image-color="White"/> 
    <Image image-view-type="Large" image-color="Yellow"/> 
    <Image image-view-type="small" image-color="White"/> 
    <Image image-view-type="small" image-color="Yellow"/> 
<DeptCode>555555</DeptCode> 
</product> 

作爲簡短的解釋:首先定義一個鍵排序

<xsl:key name="prodId" match="row" use="aaa" /> 

,然後選擇具有相同的所有行此密鑰的值:

<xsl:for-each select="row[generate-id() = 
     generate-id(key('prodId', aaa)[1])]"> 

這些是具有唯一值aaa的兩行。
然後遍歷行集中具有相同值aaa作爲當前唯一PRODID所有行:

<xsl:for-each select="key('prodId', aaa)"> 

Muenchian分組的詳細本文中通過傑尼·坦尼森描述http://www.jenitennison.com/xslt/grouping/muenchian.xml

作爲附加的參考對於XSLT分組可以看看http://www.dpawson.co.uk/xsl/sect2/N4486.html

+0

** 1 **這是Muenchian分組的不正確(不完整)實現。而不是''您應該使用''。這既簡單又高效(並且不需要變量)。 ---- ** 2。**您假定OP使用XSLT 1.0。如果他們這樣做,那麼這個''不適用於他們。 –

+0

@ michael.hor257k感謝您的建議,更新問題1. –

+0

@ michael.hor257k對於問題2 - 取決於xslt處理器,'works'例如與撒克遜9.5.1.6,但不與6.5.5。一般來說,爲不同的項目使用相同的節點名稱是個不錯的主意(並且可能實際輸入xml具有唯一的節點名稱,而這是示例xml中的複製/粘貼錯誤)。感謝提及,因爲與2.0一起工作了太久,所以往往會忘記一些1.0限制。 –

0

希望這有助於

<xsl:key name="data" match="row" use="bbb"/> 
    <xsl:output method = "xml" omit-xml-declaration = "no"/> 
    <xsl:template match="/*"> 
    <root> 
     <xsl:for-each select="row[count(. | key('data', bbb)[1]) = 1]"> 
     <product> 
      <xsl:attribute name="product-id"> 
      <xsl:value-of select="aaa"/> 
      </xsl:attribute> 
      <Name> 
      <xsl:value-of select="bbb"/> 
      </Name> 
      <Image> 
      <xsl:for-each select="key('data',bbb)"> 
       <Image> 
       <xsl:attribute name="image-view-type"> 
        <xsl:value-of select="ddd"/> 
       </xsl:attribute> 
       <xsl:attribute name="image-color"> 
        <xsl:value-of select="eee"/> 
       </xsl:attribute> 
       </Image> 
      </xsl:for-each> 
      </Image> 
      <DeptCode> 
      <xsl:value-of select="ddd[string(number(.)) != 'NaN']"/> 
      </DeptCode> 
     </product> 
     </xsl:for-each> 
    </root> 
    </xsl:template>