从运行的文本中删除超过n个连续的br标签

时间:2016-02-10 12:42:32

标签: html xml xslt

我有一些富文本输入,并且只允许最多连续两个<br>标记。

我找到了一个很好的答案:XSLT: remove duplicate br-tags from running text

但是我需要最多允许两个<br>个标记。更一般的问题是:如何允许最多n个连续的<br>标签?

示例输入:

    <p>
        Lorem ipsum...<br>
        <br>
        <br>

        ..dolor sit
    </p>

需要输出:

    <p>
        Lorem ipsum...<br>
        <br>

        ..dolor sit
    </p>

示例输入2:

    <p>
        Lorem ipsum...<br>
        lorem ... <br>
        <br>
        <br>

        ..dolor sit
    </p>

需要输出:

    <p>
        Lorem ipsum...<br>
        lorem ... <br>
        <br>

        ..dolor sit
    </p>

3 个答案:

答案 0 :(得分:1)

尝试这个

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

    <xsl:template match="br">
        <xsl:if test="not(preceding-sibling::node()
            [not(self::text() and normalize-space(.) = '')][2]
            [self::br])">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()" />
            </xsl:copy>
        </xsl:if>
    </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:1)

首先,请确保您拥有XHTML,因此<br/>代替<br>!然后:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output encoding="UTF-8" method="xml" version="1.0" indent="yes"/>
    <!-- Catch-all templates -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="processing-instruction()">
        <xsl:copy/>
    </xsl:template>
    <!-- specific part -->
    <xsl:template match="br">
        <xsl:if test="not(preceding-sibling::node()[local-name() or normalize-space()][1][local-name()='br']) or not(preceding-sibling::node()[local-name() or normalize-space()][2][local-name()='br'])">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

根据您想要允许的直接跟随的<br>之间的数量,您可以添加更多相同内容,例如对于第三个:or not(preceding-sibling::node()[local-name() or normalize-space()][3][local-name()='br']),第四个or not(preceding-sibling::node()[local-name() or normalize-space()][4][local-name()='br'])等。

答案 2 :(得分:0)

在样式表中使用以下代码:

   <!-- set desired threshold here -->
   <xsl:variable name="brThreshold" select="2"/>

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

    <xsl:template match="br[count(preceding-sibling::node()[not(self::text() and normalize-space(.) = '')][position() &lt;= $brThreshold][self::br]) = $brThreshold]">
        <!-- delete this br -->
    </xsl:template>