我是XSLT的初学者,但必须解决以下问题,并希望StackOfJoel中的一些聪明人能够帮助我: 我有一些工作xslt代码(1.1!不能使用2.0),它将XHTML转换为XML,新要求是:
问题是:我无法直接在模板匹配中匹配属性,因为我必须使attributevalue-match不区分大小写(我使用translate - 是否还有其他方法可以直接在模板匹配中使用?我知道问题#13620725,但其解决方案不适用于afaik)
因此,正如您在示例代码中所看到的那样。数据,我必须找到那些属性“class”设置为'req'(或'REQ',或'reQ'等等)的div,将它们转换为一个单独的新元素'NUREQ',然后删除周围的桌子。但对于任何其他div(没有这个特定属性),请将标准转换为元素,但保留表格!
正如您所看到的,我使用translate()使其不区分大小写,因此我无法在模板匹配中使用它。 当然,我的普通XSL更长,过滤和转换许多其他元素&属性,但我把它提炼到了本质。 有没有人有想法,可以帮助我吗?
一个xhtml测试数据文件:
<?xml version="1.0" encoding="UTF-8"?>
<html>
<head> <title></title> <style type="text/css"/></head>
<body>
<div class="somethingelse">inside std div with class</div>
<div style="page-break-after">inside std div with style</div>
<table><tbody><tr><th></th><td>
Normal Table Cell should be kept
</td></tr></tbody></table>
<table><tr><td>
<div class="req">
22
</div>
</td></tr></table>
<table><tr><td>
<div class="somethingelse">
44
</div>
</td></tr></table>
<table><tr><td>
<div >
keep div with no class 55
</div>
</td></tr></table>
<div> some additional data </div>
</body>
</html>
必需输出(奇怪的格式只是为了简洁和可见性):
<?xml version="1.0" encoding="UTF-8"?>
<segment>
<text class="somethingelse">inside std div with class</text>
<text style="page-break-after">inside std div with style</text>
<table><tbody><tr><th/><td>
Normal Table Cell should be kept with table
</td></tr></tbody></table>
<NUREQ number="22"/>
<table><tr><td>
<text class="somethingelse">
44
</text>
</td></tr></table>
<table><tr><td>
<text>
keep div with no class 55
</text>
</td></tr></table>
<text> some additional data </text>
我当前的xslt文件(没有必要的更改):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="lowercase" select="'abcdefghijklmnopqrstuvwxyz'" />
<xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
<xsl:template match="/">
<segment>
<xsl:apply-templates />
</segment>
</xsl:template>
<xsl:template match="div">
<xsl:choose>
<xsl:when test="contains(translate(@class, $uppercase, $lowercase), 'somethingelse')">
<text class="{translate(@class, $uppercase, $lowercase)}">
<xsl:apply-templates/>
</text>
</xsl:when>
<xsl:when test="contains(translate(@style, $uppercase, $lowercase), 'page-break-after')">
<text style="{translate(@style, $uppercase, $lowercase)}">
<xsl:apply-templates/>
</text>
</xsl:when>
<xsl:otherwise>
<text>
<xsl:apply-templates/>
</text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="caption|tbody|thead|tr|table|th|td">
<xsl:element name="{name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
我围绕以下代码片段进行了测试(比试验更多的错误),但它仍然是
不执行std要求的转换div =&gt;其他div的文本(44,55)
<xsl:template match = "table/tr/td/div">
<xsl:choose>
<xsl:when test="contains(translate(@class, $uppercase, $lowercase), 'req')">
<xsl:element name="NUREQ">
<xsl:attribute name="number">
<xsl:value-of select="normalize-space(text())" />
</xsl:attribute>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="table"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
答案 0 :(得分:0)
你需要XPath来做你想要的。它必须在表元素级别完成,因为这是您希望阻止显示的元素,但仅在一个实例中。我现在为表元素分离了一个模板。
<xsl:template match="caption|tbody|thead|tr|th|td">
<xsl:element name="{name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="table">
<xsl:choose>
<xsl:when test=".//div[translate(@class, $uppercase, $lowercase)='req']">
<xsl:element name="NUREQ">
<xsl:attribute name="number">
<xsl:value-of select="normalize-space(.//div)" />
</xsl:attribute>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="table">
<xsl:apply-templates/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
我希望这会有所帮助。