匹配动态 XSLT 模板



好的,所以我有一个似乎无法解决的 xslt 问题。这是我第二次尝试提出问题,请不要标记为重复。

我的问题是我想在我的文档中的第四个<p>标签之后包含一些 HTML。问题是可能存在带有属性class="exclude"<p>标签

如果<p>标签具有该类,我不想呈现该段落。同时,我仍然想在第 4 段之后呈现我包含的 html,无论有多少<p class="excludes"

编辑::这是我之前使用的 xsl。这会将我包含的 html 放入第 4 段。

<xsl:template match="content/p[position() = 4]">
     content include<xsl:apply-templates /></p>
</xsl:template> 

以下是一些示例输入/输出

首先是没有<p class="excludes">的基本示例 我的输入是:

<body>
<p></p>
<p></p>
<p></p>
<p></p>
include new HTML here
<p></p>
...
</body>

在该示例中,html 在通过我的 xslt 后在第 4 段之后呈现得很好。

但是,我需要考虑<p class="exclude">

这是一个更复杂的示例<p class="exclude" being used >

<body>
<p class="exclude"></p> (should not be rendering on page)
<p></p>
<p></p>
<p></p>
<p></p>
include new HTML here
<p></p>
...
</body>

请注意,在此示例中,包含的 HTML 出现在第 5 个*段落之后,因为第一个段落不应该在页面上呈现,但同时我希望呈现的 HTML 包含在第 4 个呈现段落之后。让我们再看一个更复杂的例子。

<body>
<p class="exclude"></p> (this should not be rendering on page)
<p></p>
<p class="exclude"></p> (this should not be rendering on page)
<p class="exclude"></p> ...
<p></p>
<p class="exclude"></p> ...
<p></p>
<p class="exclude"></p> ...
<p class="exclude"></p> ...
<p class="exclude"></p> ...
<p></p>
new HTML include here
<p></p>
...
<body>
<p class="exclude"></p>

现在,在我的最后一个示例中,您可以看到添加了多个<p class="excludes",是的,我仍然希望新的 html 内容在第 4 个呈现段落之后呈现,或者在本例中是所有段落的第 11 个总数。

如果有人有任何 xslt 可以帮助我实现这一目标,那就太好了。请记住,我正在使用xslt 1.0提前感谢

这是另一个 XSLT 1.0 样式表选项。

在这一点中,我试图考虑评论中提到的p元素的"正常处理"。

在此示例中,我添加处理指令只是为了显示已处理p。可以替换或删除它,具体取决于您在 XSLT 中执行的操作。

XML 输入

<body>
    <p class="exclude">delete1</p>
    <p>keep1</p>
    <p class="exclude">delete2</p>
    <p class="exclude">delete3</p>
    <p>keep2</p>
    <p class="exclude">delete4</p>
    <p>keep3</p>
    <p class="exclude">delete5</p>
    <p class="exclude">delete6</p>
    <p class="exclude">delete7</p>
    <p>keep4</p>
    <p>keep5</p>
    <p class="exclude">delete8</p>
</body>

XSLT 1.0(使用 Xalan 和 Saxon 6.5.5 测试)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <!--Strip p if class attribute value is exclude.-->
    <xsl:template match="p[@class='exclude']"/>
    <!--Special handling of the 4th non-exclude p. Call the "normal" template to 
        handle any other p processing and then output the additional HTML.-->
    <xsl:template match="p[not(@class='exclude')][count(preceding::p[not(@class='exclude')])+1=4]">
        <xsl:call-template name="normal"/>      
        <b>ADDITIONAL HTML HERE</b>
    </xsl:template>
    <!--This is the "normal" processing of "p". For the example, just adding a PI.-->
    <xsl:template match="p" name="normal">
        <xsl:copy>
            <xsl:processing-instruction name="processed">normally</xsl:processing-instruction>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>     
    </xsl:template>
</xsl:stylesheet>

输出

<body>
   <p><?processed normally?>keep1</p>
   <p><?processed normally?>keep2</p>
   <p><?processed normally?>keep3</p>
   <p><?processed normally?>keep4</p>
   <b>ADDITIONAL HTML HERE</b>
   <p><?processed normally?>keep5</p>
</body>

对于您正在处理的每个p,请检查...

<xsl:if test="count(preceding::p[not(@class='exclude')])=4">
   render your html here
</xsl:if>

编辑

另外,与您的进一步问题有关:

<xsl:apply-tempates select="p[not(@class='exlude')]"/>
<xsl:template match="p">
   <p>
     <xsl:if test="count(preceding::p[not(@class='exclude')])=4">
      render your html here
   </xsl:if>
   </p>
</xsl:template>

如果你不想要所有其他的P,你可以把计数放在匹配中。

编辑

我已经看了你更新的问题,我不确定它是如何工作的,因为你有一个不平衡的模板(你有一个结束的p,但没有一个开始的? - 我认为这是一个错字。你还说你的p在体内,但你在内容/p上匹配。内容标记从何而来。

无论如何,通过更正,假设您的原始模板是:

<xsl:template match="content/p[position() = 4]">
    <p>content include<xsl:apply-templates /></p> 
</xsl:template> 

它有效,只需将其更改为

只需将其更改为

<xsl:template match="p[count(preceding::p[not(@class='exclude')])=4]">
    <p>content include<xsl:apply-templates /></p> 
</xsl:template> 

那会给你正确的事情

最新更新