如果attribute = value,则删除周围(表)层(没有直接属性匹配!)

时间:2013-10-25 15:42:32

标签: xml xslt xpath

我是XSLT的初学者,但必须解决以下问题,并希望StackOfJoel中的一些聪明人能够帮助我: 我有一些工作xslt代码(1.1!不能使用2.0),它将XHTML转换为XML,新要求是:

  • 某个div元素(具有特定的属性值)始终包含在表中;应该将div转换为新元素(NUREQ),并删除所有周围的表结构
  • 应保留任何其他表格,并且不应删除任何其他div,而是将其自身转换为不同的元素(文本)!

问题是:我无法直接在模板匹配中匹配属性,因为我必须使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>

我围绕以下代码片段进行了测试(比试验更多的错误),但它仍然是

  • 不会使用req-class(testdata中的22)来删除div周围的表格。
  • 不执行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> 
    

1 个答案:

答案 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>

我希望这会有所帮助。