如何在一个xml节点上应用多个xsl-templates [英] How to apply more then one xsl-templates on one xml node
问题描述
这是我的问题:
我有HTML文档和CSS样式。我需要将这些样式移动到主体中的元素中,并将它们从样式标记中移除。
我为每个CSS样式和值创建了xpath的帮助器,放在那里。然后它生成XSL文档并将其应用于HTML。
有时,需要将多个xsl模板应用于同一个节点(相同匹配) 。
如何将它们全部应用?
以下是HTML的一个例子:
< html lang =en>
< head>
< META HTTP-EQUIV =Content-TypeCONTENT =text / html; CHARSET = utf-8/>
< style type =text / css>
.right-aligned {text-align:right!important; }
.full-width {width:100%!important;显示:inline-block; }
< / style>
< / head>
< body>
< table class =header>
< tr>
< td class =icon>
< img alt =次要src =Picture_SRC/>
< / td>
< td>
< div class =辅助全角右对齐> Blah:测试< / div>
< / td>
< / tr>
< / table>
< / body>
< / html>
还有需要为这个HTML完成的XSL转换:
< xsl:template match =// * [contains(@ class,'right-aligned')and @style]>
< xsl:attribute name =style>
< xsl:value-of select =concat(。,'text-align:right!important;')/>
< / xsl:attribute>
< / xsl:template>
< xsl:copy>
< xsl:attribute name =style> text-align:right!important;< / xsl:attribute>
< xsl:apply-templates select =@ * | node()/>
< / xsl:copy>
< / xsl:template>
< xsl:template match =// * [contains(@ class,'full-width')and @style]>
< xsl:attribute name =style>
< xsl:value-of select =concat(。,'width:100%!important; display:inline-block;')/>
< / xsl:attribute>
< / xsl:template>
< xsl:copy>
< xsl:apply-templates select =@ * | node()/>
< / xsl:copy>
< / xsl:template>
重要的事情是:HTML不是静态的,它会改变...所以我不能让静态XSL。
以下是您可以使用 如果您可以使用XSLT 2.0,则可以使用优先级而不是模式来简化此操作, here is my problem: I have HTML Document with CSS Styles. I need to move these styles into the elements in the body and remove them from style tag. I made helper that makes xpath for each css style and value which needs to be put there. Then it generates XSL documents and applies it to the HTML. The thing is sometimes there are multiple xsl-templates that needs to be applied to the same Node (same match). And just the first one is getting applied, others are ignored. How i can apply them all? Here is one example of the HTML: And there is the XSL Transformations that needed to be done for this HTML: Important thing: the HTML is not static and it changes ... so i can't make static XSL. Here is one way you could do it, by use of If you could use XSLT 2.0, you could simplify this by use of priorities, instead of modes, and
这篇关于如何在一个xml节点上应用多个xsl-templates的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!模式
$ c $>
< xsl:template match =@ * | node()>
< xsl:copy>
< xsl:apply-templates select =@ * | node()/>
< / xsl:copy>
< / xsl:template>
< xsl:template match =@ class>
< xsl:attribute name =style>
< xsl:text> ;;< / xsl:text>
< / xsl:if>
< / xsl:template>
< xsl:template match =@ style/>
< xsl:text> text-align:right!important;< / xsl:text>
< / xsl:if>
< xsl:text>宽度:100%!重要; display:inline-block;< / xsl:text>
< / xsl:if>
< / xsl:template>
< / xsl:stylesheet>
xsl:next-match
可以找到下一个匹配模板,优先级较低。
< xsl:stylesheet xmlns:xsl =http://www.w3.org/1999/XSL/Transformversion =1.0>
< xsl:template match =@ * | node()>
< xsl:copy>
< xsl:apply-templates select =@ * | node()/>
< / xsl:copy>
< / xsl:template>
< xsl:template match =@ classpriority =10>
< xsl:attribute name =style>
< xsl:text> ;;< / xsl:text>
< / xsl:if>
< xsl:next-match />
< / xsl:attribute>
< / xsl:template>
< xsl:template match =@ style/>
< xsl:next-match />
< / xsl:template>
< xsl:next-match />
< / xsl:template>
< xsl:template match =@ class/> <! - 停止应用内置模板 - >
< / xsl:stylesheet>
<html lang="en">
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=utf-8"/>
<style type="text/css">
.right-aligned { text-align: right !important; }
.full-width { width: 100% !important; display: inline-block; }
</style>
</head>
<body>
<table class="header">
<tr>
<td class="icon">
<img alt="Minor" src="Picture_SRC" />
</td>
<td>
<div class="secondary full-width right-aligned">Blah: Test</div>
</td>
</tr>
</table>
</body>
</html>
<xsl:template match="//*[contains(@class,'right-aligned') and @style]">
<xsl:attribute name="style">
<xsl:value-of select="concat(., 'text-align: right !important;')"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="//*[contains(@class,'right-aligned') and not(@style)]">
<xsl:copy>
<xsl:attribute name="style">text-align: right !important;</xsl:attribute>
<xsl:apply-templates select="@*| node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//*[contains(@class,'full-width') and @style]">
<xsl:attribute name="style">
<xsl:value-of select="concat(., 'width: 100% !important; display: inline-block;')"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="//*[contains(@class,'full-width') and not(@style)]">
<xsl:copy>
<xsl:attribute name="style">width: 100% !important; display: inline-block;</xsl:attribute>
<xsl:apply-templates select="@*| node()"/>
</xsl:copy>
</xsl:template>
mode
attributes, to apply each template one after another<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="@class">
<xsl:attribute name="style">
<xsl:if test="@style">
<xsl:value-of select="@style" />
<xsl:text>;</xsl:text>
</xsl:if>
<xsl:apply-templates select="." mode="right-aligned" />
</xsl:attribute>
</xsl:template>
<xsl:template match="@style" />
<xsl:template match="@class" mode="right-aligned">
<xsl:if test="contains(.,'right-aligned')">
<xsl:text>text-align: right !important;</xsl:text>
</xsl:if>
<xsl:apply-templates select="." mode="full-width" />
</xsl:template>
<xsl:template match="@class" mode="full-width">
<xsl:if test="contains(.,'full-width')">
<xsl:text>width: 100% !important; display: inline-block;</xsl:text>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
xsl:next-match
to find the next matching template with a lower priority.<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="@class" priority="10">
<xsl:attribute name="style">
<xsl:if test="@style">
<xsl:value-of select="@style" />
<xsl:text>;</xsl:text>
</xsl:if>
<xsl:next-match />
</xsl:attribute>
</xsl:template>
<xsl:template match="@style" />
<xsl:template match="@class[contains(.,'right-aligned')]" priority="9">
<xsl:text>text-align: right !important;</xsl:text>
<xsl:next-match />
</xsl:template>
<xsl:template match="@class[contains(.,'full-width')]" priority="8">
<xsl:text>width: 100% !important; display: inline-block;</xsl:text>
<xsl:next-match />
</xsl:template>
<xsl:template match="@class" /> <!-- Stop the built-in template applying -->
</xsl:stylesheet>