xslt:如何使用新标签包装不同的标签

时间:2016-09-14 20:23:12

标签: xslt-2.0

我不确定这对xslt是否可行,但是这里有。 我需要将文章中的xml分成不同的部分。

我需要获取所有xml,直到第一个类名为全宽的div并将其包含在类名为 narrow-wrap 的div中。
全角 div需要使用类名为 wide-wrap 的div进行换行。

然后一个带有类narrow-wrap的新div启动并且所有xml直到具有类全宽的下一个div进入那个。等等。

这是xml的简化版本。标签可以包含嵌套内容以及属性。

<p>lorem</p>
<div>ipsum</div>
<div class="full-width">
    <img src="image.jpg" />
</div>
<p>lorem</p>
<p>ipsum</p>
<div class="full-width">
    <img src="image.jpg" />
</div>
<div class="narrow-width">
    <img src="image.jpg" />
</div>
<p>lorem</p>
<div class="full-width">
    <img src="image.jpg" />
</div>
<div class="full-width">
    <img src="image.jpg" />
</div>
<table>ipsum</table>
<p>lorem</p>
<p>ipsum</p>        
<div class="narrow-width">
    <img src="image.jpg" />
</div>

这就是变换后我需要的样子:

<div class="narrow-wrap">
    <p>lorem</p>
    <div>ipsum</div>
</div>

<div class="wide-wrap">
    <div class="full-width">
        <img src="image.jpg" />
    </div>
</div>

<div class="narrow-wrap">
    <p>lorem</p>
    <p>ipsum</p>
</div>

<div class="wide-wrap">
    <div class="full-width">
        <img src="image.jpg" />
    </div>
</div>

<div class="wide-wrap">
    <div class="narrow-width">
        <img src="image.jpg" />
    </div>
</div>

<div class="narrow-wrap">
    <p>lorem</p>
</div>

<div class="wide-wrap">
    <div class="full-width">
        <img src="image.jpg" />
    </div>
</div>

<div class="wide-wrap">
    <div class="full-width">
        <img src="image.jpg" />
    </div>
</div>

<div class="narrow-wrap">
    <table>ipsum</table>
    <p>lorem</p>
    <p>ipsum</p>        
    <div class="narrow-width">
        <img src="image.jpg" />
    </div>
</div>

全宽部分的xsl将是这样的:

<xsl:template match="div[contains(concat(' ', @class, ' '), ' full-width ')]"> 
    <div>
        <xsl:attribute name="class">
            wide-wrap
        </xsl:attribute>
        <xsl:copy-of select="."></xsl:copy-of>
    </div>
</xsl:template>

使用类narrow-wrap将所有其他内容包装在div块中的部分超出了我的范围。 这是可能的,如果是的话,怎么样?

1 个答案:

答案 0 :(得分:1)

请参阅https://www.w3.org/TR/xslt20/#grouping-examples中的group-adjacent示例并尝试<xsl:for-each-group select="*" group-adjacent="not (@class = 'full-width')">,然后,如示例中所示,检查密钥并分别包装current-group ()组中的每个项目。< / p>

使用这种方法得到

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="body">
        <xsl:copy>
            <xsl:for-each-group select="*" group-adjacent="not (@class = 'full-width')">
                <xsl:choose>
                    <xsl:when test="current-grouping-key()">
                        <div class="narrow-wrap">
                            <xsl:apply-templates select="current-group()"/>
                        </div>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:apply-templates select="current-group()"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="div[contains(concat(' ', @class, ' '), ' full-width ')]"> 
        <div class="wide-wrap">
            <xsl:copy-of select="."></xsl:copy-of>
        </div>
    </xsl:template>
</xsl:transform>

在线http://xsltransform.net/6rewNxQ