让我们说我写了一个简单的xslt,它可以从一条消息转换到另一条消息,有什么方法可以自动生成逆转吗?
原创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>
答案 0 :(得分: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
参数的值,可以来回切换转换方向。
答案 1 :(得分:1)
对于计算机科学专业的学生来说,确定是否有一类可逆的XSLT转换可能是一项有趣的练习。这当然意味着转型必须是无损的。最明显的候选者是除了重命名元素之外什么都不做的转换,但即便如此,我认为很难(不知道源文档的词汇和结构)来证明样式表没有将两个不同的输入名称映射到相同的输出名称。所以我认为这最终会成为一个相当小的集合。
在实践中,有用的人还可以考虑添加冗余信息的转换,例如HTML标头,以及两个输入元素映射到同一输出元素但具有不同属性的转换(比如div class =“X”) “其中X允许重构输入元素名称”。
答案 2 :(得分: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>