2012-05-23 16 views
0

我正在獲取需要轉換爲另一種標準類型的XML文件。我的指尖上有XSLT2,我無法控制任何一個文件的格式。第一個有兩個使用數字值的序列來匹配它們。第一個序列可以有0..n秒。如何通過XSLT將兩個並排XML結構映射到一起?

一個例子是:

輸入:

<foo> 
<structure name="items"> 
    <item> 
     <itemCode>1</itemCode> 
     <itemValue>1111</itemValue> 
    </item> 
    <item> 
     <itemCode>2</itemCode> 
     <itemValue>2222</itemValue> 
    </item> 
</structure> 
<structure name="subItems"> 
    <subItem> 
     <itemCode>1</itemCode> 
     <subValue>12</subValue> 
     <subType>MISC</subType> 
    </subItem> 
    <subItem> 
     <itemCode>1</itemCode> 
     <subValue>15</subValue> 
     <subType>MISC2</subType> 
    </subItem> 
    <subItem> 
     <itemCode>2</itemCode> 
     <subValue>40</subValue> 
     <subType>MISC</subType> 
    </subItem> 
</structure> 
</foo> 

而且我想輸出是

<bar> 
<items> 
    <item> 
     <code>1</code> 
     <value>1111</value> 
     <subItems> 
      <subItem> 
       <subValue>12</subValue> 
       <subType>MISC</subType> 
      </subItem> 
      <subItem> 
       <subValue>15</subValue> 
       <subType>MISC2</subType> 
      </subItem>    
     </subItems> 
    </item> 
    <item> 
     <code>2</code> 
     <value>2222</value> 
     <subItems> 
      <subItem> 
       <subValue>40</subValue> 
       <subType>MISC</subType> 
      </subItem> 
     </subItems> 
    </item>   
</items> 
</bar> 

我一直不成功映射item.itemCode簡單,因爲subItem.itemCode看到下一個之前,XSLT處理器似乎退出第一個序列。我無法知道有多少我會在任何一個序列中獲得,所以我不能做一張靜態地圖。

任何想法?

在此先感謝

+0

我不清楚你的意思*第一個序列可能有0..n秒*。請解釋。 – Borodin

回答

1

另一種方法來選擇合適的子值是使用關鍵:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:key name="subitems-by-code" match="subItem" use="itemCode"/> 

    <xsl:template match="foo"> 
    <bar> 
     <items> 
     <xsl:apply-templates select="structure[@name='items']"/> 
     </items> 
    </bar> 
    </xsl:template> 

    <xsl:template match="item"> 
    <item> 
     <xsl:copy-of select="*"/> 
     <subItems> 
     <xsl:apply-templates select="key('subitems-by-code', itemCode)"/> 
     </subItems> 
    </item> 
    </xsl:template> 

    <xsl:template match="subItem"> 
    <subItem> 
     <xsl:copy-of select="subValue|subType"/> 
    </subItem> 
    </xsl:template> 
</xsl:stylesheet> 
0

我不是通常高興發佈一個完整的解決方案,但問題看起來有趣,所以我寫了這一點。

請再詢問一下您是否需要任何闡述。

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"> 

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

    <xsl:template match="/foo"> 
     <bar> 
      <items> 
       <xsl:apply-templates select="structure[@name='items']/item"> 
        <xsl:sort select="itemCode" /> 
       </xsl:apply-templates> 
      </items> 
     </bar> 
    </xsl:template> 

    <xsl:template match="item"> 

      <item> 
       <code> 
        <xsl:value-of select="itemCode" /> 
       </code> 
       <value> 
        <xsl:value-of select="itemValue" /> 
       </value> 
       <subItems> 
        <xsl:apply-templates select="/foo/structure[@name='subItems']/subItem[itemCode=current()/itemCode]" /> 
       </subItems> 
      </item> 

    </xsl:template> 

    <xsl:template match="subItem"> 

     <subItem> 
      <xsl:copy-of select="subValue"/> 
      <xsl:copy-of select="subType"/> 
     </subItem> 

    </xsl:template> 

</xsl:stylesheet> 

輸出

<?xml version="1.0" encoding="utf-8"?> 
<bar> 
    <items> 
     <item> 
     <code>1</code> 
     <value>1111</value> 
     <subItems> 
      <subItem> 
       <subValue>12</subValue> 
       <subType>MISC</subType> 
      </subItem> 
      <subItem> 
       <subValue>15</subValue> 
       <subType>MISC2</subType> 
      </subItem> 
     </subItems> 
     </item> 
     <item> 
     <code>2</code> 
     <value>2222</value> 
     <subItems> 
      <subItem> 
       <subValue>40</subValue> 
       <subType>MISC</subType> 
      </subItem> 
     </subItems> 
     </item> 
    </items> 
</bar> 
0

它看起來對我來說,一個簡單的分組問題。

<xsl:for-each-group select="items/item, subItems/subItem" group-by="itemCode"> 
    <item> 
    <code><xsl:value-of select="current-group()[self::item]/itemCode"/></code> 
    <value><xsl:value-of select="current-group()/itemValue"/></value> 
    <subItems> 
     <xsl:copy-of select="current-group()[self::subItem]/(subValue, subType)"/> 
    </subItems> 
    </item> 
</xsl:for-each-group>