2013-04-24 50 views
1

可以說我已經寫了一個簡單的xslt從一個消息轉換到另一個有沒有什麼辦法可以自動生成逆?自動反轉一個xsl

原始XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
     <xsl:template match="/"> 
     <hello> 
     <xsl:for-each select="/hello/greeting">   
     <H1> 
       <xsl:value-of select="."/> 
     </H1> 
     </xsl:for-each> 
     </hello> 
     </xsl:template> 
    </xsl:stylesheet> 

期望中的XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:template match="/"> 
    <hello> 
    <xsl:for-each select="/hello/H1">   
     <greeting> 
      <xsl:value-of select="."/> 
     </greeting> 
    </xsl:for-each> 
    </hello> 
    </xsl:template> 
</xsl:stylesheet> 
+1

你知道SQL Server如何做到這一點嗎?閱讀關於:交易,交易日誌,展開/中止交易。使交易成爲交易系統中的交易。 – 2013-04-24 14:43:48

+0

感謝您的幫助,不幸的是,這似乎並沒有解決我的問題,因爲我希望轉換的實際xsls要大得多,並將行業CDM映射到企業CDM。我真的希望有人知道一個很酷的工具可以做到這一點。 – user2313879 2013-04-29 03:57:10

+1

user2313879,人們向你解釋說,在一般情況下,扭轉變革*是不可能的 - 你還想要什麼?像函數一樣 - 只有一小部分函數是可逆的 - 當用不同的參數調用時,它們具有不同的值。大多數功能*不具有此屬性。轉換是源XML文檔以及提供的全局參數以及全局上下文的功能。 – 2013-04-29 04:06:21

回答

2

不,沒有一種通用的方法來反轉XSLT。事實上,我認爲大多數XSLT是不可逆的。這是可能的,然而,設計的上方,使得它可以在向前方向或相反的方向,通過改變一個參數值來運行例如:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:exslt="http://exslt.org/common"> 
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> 
    <xsl:param name="direction" select="'forward'" /> 

    <xsl:variable name="mappingNF"> 
    <map from="greeting" to="H1" /> 
    <map from="pleasantry" to="H2" /> 
    </xsl:variable> 
    <xsl:variable name="mapping" select="exslt:node-set($mappingNF)" /> 

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

    <xsl:template match="*" mode="copy"> 
    <xsl:call-template name="Copy" /> 
    </xsl:template> 

    <xsl:template match="*"> 
    <xsl:variable name="mappingItem" 
        select="$mapping/*[$direction = 'forward' and @from = local-name(current()) or 
           $direction = 'reverse' and @to = local-name(current())]" /> 

    <xsl:apply-templates select="current()[$mappingItem]" mode="rename"> 
     <xsl:with-param name="mappingItem" select="$mappingItem" /> 
    </xsl:apply-templates> 
    <xsl:apply-templates select="current()[not($mappingItem)]" mode="copy" /> 
    </xsl:template> 

    <xsl:template match="*" mode="rename"> 
    <xsl:param name="mappingItem" /> 

    <xsl:element name="{$mappingItem/@to[$direction = 'forward'] | 
         $mappingItem/@from[$direction = 'reverse']}"> 
     <xsl:apply-templates select ="@* | node()" /> 
    </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

mappingNF指示節點名之間的對應關係,這樣就可以根據需要增加儘可能多的map。通過更改「正向」和「反向」之間參數direction的值,可以來回切換轉換的方向。

0

我不認爲有一種方法可以自動生成一個相反的方向

但是,您可以重用大部分的東西在目前的XSL中,如果模板做的是一樣的

在你的例如它會是

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:template match="/"> 
    <hello> 
    <xsl:for-each select="/hello/H1 | /hello/greeting">  
    <H1> 
      <xsl:value-of select="."/> 
    </H1> 
    </xsl:for-each> 
    </hello> 
    </xsl:template> 
</xsl:stylesheet> 
1

對於計算機科學的學生來說,也許有一個有趣的練習來確定是否有一類XSLT變換是可逆的。這當然意味着轉換必須是無損的。最明顯的候選對象是除了重命名元素之外別無他法的變換,但即使如此,我認爲這將很難(沒有關於源文檔詞彙和結構的知識)來證明樣式表沒有將兩個不同的輸入名稱映射到相同的輸出名稱。所以我認爲這將會變成一個相當小的組合。

在實踐中有用的是,還需要考慮添加冗餘信息的轉換,例如HTML標頭,或許兩個輸入元素映射到同一個輸出元素但具有不同屬性的轉換(比如div class =「 X「,其中X使得輸入元素名稱能夠被重構)。