2011-07-16 45 views
3

這是我的xml文件:多個XSLT文件,以單XSLT文件2個不同的XML文件

<?xml version="1.0" encoding="windows-1250"?> 
<CONTACTS> 
    <CONTACT> 
     <FirstName>Ford</FirstName> 
     <LastName>Pasteur</LastName> 
     <EMail>[email protected]</EMail> 
    </CONTACT> 
    <CONTACT> 
     <FirstName>Jack</FirstName> 
     <LastName>Sully</LastName> 
     <URL>http://www.facebook.com/profile.php?id=1000474277</URL> 
    </CONTACT> 
    <CONTACT> 
     <FirstName>Colombo</FirstName> 
     <LastName>Chao</LastName> 
     <EMail>[email protected]</EMail> 
    </CONTACT> 
</CONTACTS> 

我用下面的XSLT文件我的XML輸出的拳頭版本。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

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

    <xsl:template match="CONTACT"> 
     <xsl:copy> 
       <Customer-ID> 
       <xsl:value-of select="generate-id(.)"/> 
       </Customer-ID> 
       <xsl:copy-of select="FirstName|LastName|URL"/> 
       <Facebook-ID> 
      <xsl:choose> 
       <xsl:when test="URL"> 
        <xsl:value-of select="substring-after(URL,'?id=')"/> 
       </xsl:when> 
       <xsl:otherwise> 

       </xsl:otherwise> 
      </xsl:choose> 
     </Facebook-ID> 
      <EMAILS> 
       <xsl:apply-templates select="EMail"/> 
      </EMAILS> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="EMail"> 
     <EMail> 
      <Type><xsl:value-of select="substring-before(
        substring-after(.,'@'), 
        '.')"/> 
      </Type> 
      <Value><xsl:value-of select="."/></Value> 
     </EMail> 
    </xsl:template> 

</xsl:stylesheet> 

從上面的XSLT文件我的XML輸出的第一個版本:

<?xml version="1.0" encoding="windows-1250"?> 
<CONTACTS> 
    <CONTACT> 
    <Customer-ID>N65539</Customer-ID> 
    <FirstName>Ford</FirstName> 
    <LastName>Pasteur</LastName> 
    <EMAILS> 
    <EMail> 
    <Type>yahoo</Type> 
    <Value>[email protected]</Value> 
    </EMail> 
    </EMAILS> 
    </CONTACT> 
    <CONTACT> 
    <Customer-ID>N65546</Customer-ID> 
    <FirstName>Jack</FirstName> 
    <LastName>Sully</LastName> 
    <URL>http://www.facebook.com/profile.php?id=1000474277</URL> 
    <Facebook-ID>1000474277</Facebook-ID> 
    <EMAILS/> 
    </CONTACT> 
    <CONTACT> 
    <Customer-ID>N65553</Customer-ID> 
    <FirstName>Colombo</FirstName> 
    <LastName>Chao</LastName> 
    <EMAILS> 
    <EMail> 
    <Type>liberto</Type> 
    <Value>[email protected]</Value> 
    </EMail> 
    </EMAILS> 
    </CONTACT> 
</CONTACTS> 

這是我第二XSLT文件:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" indent="yes"/> 
<xsl:strip-space elements="*"/> 
<xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="CONTACT"> 
<xsl:copy> 
    <Customer-ID> 
     <xsl:value-of select="Customer-ID"/> 
    </Customer-ID> 

    <FirstName> 
     <xsl:value-of select="FirstName"/> 
    </FirstName> 

    <LastName> 
     <xsl:value-of select="LastName"/> 
    </LastName> 

    <gmail> 
      <xsl:value-of select="EMAILS/EMail[Type='gmail']/Value"/> 
    </gmail> 

    <yahoo> 
      <xsl:value-of select="EMAILS/EMail[Type='yahoo']/Value"/> 
    </yahoo> 

    <liberto> 
      <xsl:value-of select="EMAILS/EMail[Type='liberto']/Value"/> 
    </liberto> 

    <URL> 
      <xsl:value-of select="URL"/> 
    </URL> 

    <Facebook-ID> 
      <xsl:value-of select="Facebook-ID"/> 
    </Facebook-ID> 

     </xsl:copy> 
</xsl:template> 

這是我最後的XML輸出來自第二個XSLT文件:

<?xml version="1.0" encoding="windows-1250"?> 
<CONTACTS> 

    <CONTACT> 
    <Customer-ID>N65539</Customer-ID> 
    <FirstName>Ford</FirstName> 
    <LastName>Pasteur</LastName> 
    <gmail/> 
    <yahoo>[email protected]</yahoo> 
    <liberto/> 
    <URL/> 
    <Facebook-ID/> 
    </CONTACT> 

    <CONTACT> 
    <Customer-ID>N65546</Customer-ID> 
    <FirstName>Jack</FirstName> 
    <LastName>Sully</LastName> 
    <gmail/> 
    <yahoo/> 
    <liberto/> 
    <URL>http://www.facebook.com/profile.php?id=1000474277</URL> 
    <Facebook-ID>1000474277</Facebook-ID> 
    </CONTACT> 

    <CONTACT> 
    <Customer-ID>N65553</Customer-ID> 
    <FirstName>Colombo</FirstName> 
    <LastName>Chao</LastName> 
    <gmail/> 
    <yahoo/> 
    <liberto>[email protected]</liberto> 
    <URL/> 
    <Facebook-ID/> 
    </CONTACT> 
</CONTACTS> 

如何合併這兩個XSLT文件作爲單個XSLT文件以獲得最終的XML輸出。

我該如何處理?因爲有兩個不同類型的xml文件。

我使用Eclipse Hellios作爲 - > XSL轉換來查看輸出。

+0

1爲努力。我已將您可在[XSLT 2.0 rec。](http://www.w3.org/TR/xslt20/#d5e12785)中找到的兩階段示例調整爲您的用例XSLT 1.0。 –

回答

3

您可以使用xsl:import重用你的XSLT文件,然後使用該技術在@ Dimitre的回答解釋如下:

<xsl:stylesheet version="1.0" 
    xmlns:exslt="http://exslt.org/common" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    exclude-result-prefixes="exslt"> 

    <xsl:import href="phase1.xsl"/> 
    <xsl:import href="phase2.xsl"/> 

    <xsl:output method="xml" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="/"> 
     <xsl:variable name="intermediate"> 
      <xsl:apply-templates select="/CONTACTS/CONTACT" mode="phase1"/> 
     </xsl:variable> 
      <CONTACTS> 
     <xsl:apply-templates select="exslt:node-set($intermediate)" 
     mode="phase2"/> 
      </CONTACTS> 
    </xsl:template> 

</xsl:stylesheet> 

其中:

  • phase1.xsl和phase2.xsl是您的兩個xslt變換
  • 變換略有修改,將mode添加到每個模板。例如,phase1.xsl變換:

    <xsl:template match="node()|@*"> 
        <xsl:copy> 
         <xsl:apply-templates select="node()|@*" mode="phase1"/> 
        </xsl:copy> 
    </xsl:template> 
    
    <xsl:template match="CONTACT" mode="phase1"> 
        <xsl:copy> 
         <Customer-ID> 
          <xsl:value-of select="generate-id(.)"/> 
         </Customer-ID> 
         <xsl:copy-of select="FirstName|LastName|URL"/> 
         <Facebook-ID> 
          <xsl:choose> 
           <xsl:when test="URL"> 
            <xsl:value-of select="substring-after(URL,'?id=')"/> 
           </xsl:when> 
           <xsl:otherwise> 
    
           </xsl:otherwise> 
          </xsl:choose> 
         </Facebook-ID> 
         <EMAILS> 
          <xsl:apply-templates select="EMail" mode="phase1"/> 
         </EMAILS> 
        </xsl:copy> 
    </xsl:template> 
    
    <xsl:template match="EMail" mode="phase1"> 
        <EMail> 
         <Type><xsl:value-of select="substring-before(
           substring-after(.,'@'), 
           '.')"/> 
         </Type> 
         <Value><xsl:value-of select="."/></Value> 
        </EMail> 
    </xsl:template> 
    

對於phase2.xsl你會用'模式= 「階段二」 明顯。

當上述條件滿足,和合併被施加到第一個輸入XML變換,得到以下輸出:

<CONTACTS> 
    <CONTACT> 
     <Customer-ID>d0e2</Customer-ID> 
     <FirstName>Ford</FirstName> 
     <LastName>Pasteur</LastName> 
     <gmail/> 
     <yahoo>[email protected]</yahoo> 
     <liberto/> 
     <URL/> 
     <Facebook-ID/> 
    </CONTACT> 
    <CONTACT> 
     <Customer-ID>d0e9</Customer-ID> 
     <FirstName>Jack</FirstName> 
     <LastName>Sully</LastName> 
     <gmail/> 
     <yahoo/> 
     <liberto/> 
     <URL>http://www.facebook.com/profile.php?id=1000474277</URL> 
     <Facebook-ID>1000474277</Facebook-ID> 
    </CONTACT> 
    <CONTACT> 
     <Customer-ID>d0e16</Customer-ID> 
     <FirstName>Colombo</FirstName> 
     <LastName>Chao</LastName> 
     <gmail/> 
     <yahoo/> 
     <liberto>[email protected]</liberto> 
     <URL/> 
     <Facebook-ID/> 
    </CONTACT> 
</CONTACTS> 
+0

「像魅力一樣工作」謝謝。 – linguini

+0

不客氣! –

4

在XSLT應用程序中經常使用執行鏈轉換,儘管完全在XSLT 1.0中完成此操作需要使用供應商特定的xxx:node-set()函數。在XSLT 2.0中,不需要這樣的擴展,因爲在那裏消除了臭名昭着的RTF數據類型。

下面是一個例子(太簡單有意義,但完全示出了這是如何完成的):

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ext="http://exslt.org/common"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/"> 
    <xsl:variable name="vrtfPass1"> 
    <xsl:apply-templates select="/*/*"/> 
    </xsl:variable> 

    <xsl:variable name="vPass1" 
     select="ext:node-set($vrtfPass1)"/> 

    <xsl:apply-templates mode="pass2" 
     select="$vPass1/*"/> 
</xsl:template> 

<xsl:template match="num[. mod 2 = 1]"> 
    <xsl:copy-of select="."/> 
</xsl:template> 

<xsl:template match="num" mode="pass2"> 
    <xsl:copy> 
    <xsl:value-of select=". *2"/> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

當這種轉變是在下面的XML文檔施加:

<nums> 
    <num>01</num> 
    <num>02</num> 
    <num>03</num> 
    <num>04</num> 
    <num>05</num> 
    <num>06</num> 
    <num>07</num> 
    <num>08</num> 
    <num>09</num> 
    <num>10</num> 
</nums> 

想要的,正確的結果產生

<num>2</num> 
<num>6</num> 
<num>10</num> 
<num>14</num> 
<num>18</num> 

說明

  1. 在第一步驟中的XML文檔變換並且結果被定義爲變量$vrtfPass1的值。這隻複製具有奇數值(不是偶數)的num元素。

  2. $vrtfPass1變量,作爲類型RTF的,是不適合的XPath直接可用的表達式所以我們將其轉換爲正常樹,使用EXSLT(由最XSLT實現1.0處理器)功能ext:node-set和限定另一個變量 - - $vPass1其值是這棵樹。

  3. 我們現在在我們轉變鏈進行第二次轉型 - 第一個轉換的結果,即保留作爲變量$vPass1的價值。不要混淆第一遍模板,我們指定新處理應該處於命名模式,稱爲「pass2」。在此模式下,任何num元素的值都乘以2。

XSLT 2.0解決方案(無RTFS):

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/"> 
    <xsl:variable name="vPass1" > 
    <xsl:apply-templates select="/*/*"/> 
    </xsl:variable> 
    <xsl:apply-templates mode="pass2" 
     select="$vPass1/*"/> 
</xsl:template> 

<xsl:template match="num[. mod 2 = 1]"> 
    <xsl:copy-of select="."/> 
</xsl:template> 

<xsl:template match="num" mode="pass2"> 
    <xsl:copy> 
    <xsl:value-of select=". *2"/> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 
+0

@karthik rangaraj:如果我很好地理解你的問題,你就會問如何對第一次轉換的結果應用第二次轉換。在我的回答中,我以一個說明該技術的例子展示了這一點。您可以使用相同的技術將您的兩個轉換鏈接在一起,或者一般情況下可以使用兩個或多個轉換鏈接。閱讀好解釋。 –

+0

偉大的技術。我理解你的技巧和解釋。 @empo:使用你的技術,一切正常。感謝您的技術。 – linguini

+0

@karthik rangaraj:不客氣。 –