2013-04-24 47 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使得输入元素名称能够被重构)。