示例输入:
<body>
<ul>
<li>
<p>Some text with <b><i><span style="color:red">formatting</span></i></b></p>
</li>
</ul>
</body>
&#39; inline&#39;元素为b
,i
或span
假设上下文节点是示例中的嵌套span
元素。
如何在没有搜索超过包含p
元素的情况下获取所有祖先内联元素?
表达式ancestor-or-self::*[self::b | self::i | self::span]
实际上应该有效,因为不能包含&#39; block&#39;的祖先内联元素。等级元素,例如p
,ul
等
但是,我想知道是否有一些可以避免的性能成本,因为我认为搜索将继续超过包含p
元素。有没有办法避免这种情况?
修改
这是我到目前为止所提出的:
<xsl:function name="my:getInlineSeq" as="element() *">
<xsl:param name="pElem" as="element()" />
<xsl:if test="$pElem[self::b | self::i | self::span]">
<xsl:sequence select="my:getInlineSeq($pElem/parent::*)" />
<xsl:sequence select="$pElem" />
</xsl:if>
</xsl:function>
但是,我不确定是否有更好的标准&#39;解决这个问题的方法。
注意:代码中的$pElem/parent::*
将始终返回一个元素,因为内联项必须具有块元素容器,例如p
,h1
等。此外,假设是最初提供的$pElem
参数始终是内联元素。
答案 0 :(得分:3)
使用
<xsl:function name="mf:block" as="element()">
<xsl:param name="inline" as="element()"/>
<xsl:sequence select="$inline/ancestor::*[self::h1 | self::h2 | self::h3 | self::h4 | self::h5 | self::h6 | self::li | self::p][1]"/>
</xsl:function>
以及关于块和内联元素的假设,您可以在ancestor-or-self::*[self::b | self::i | self::span]
到
match="span | b | i"
for $block in mf:block(.) return ancestor-or-self::*[. >> $block]
我认为(或假设你使用<xsl:variable name="block" select="mf:block(.)"/>
来ancestor-or-self::*[. >> $block]
。我不知道这是否比你的尝试更好。
试图在http://xsltransform.net/3MvmrzK
处测试表达式<xsl:template match="span | b | i">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:attribute name="inline-ancestor" select="ancestor-or-self::*[self::b | self::i | self::span]/name()"/>
<xsl:attribute name="test-block" select="for $block in mf:block(.) return ancestor-or-self::*[. >> $block]/name()"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
使用
为内联元素提供相同的结果 <p>Some text with <b inline-ancestor="b" test-block="b"><i inline-ancestor="b i" test-block="b i"><span style="color:red" inline-ancestor="b i span" test-block="b i span">formatting</span></i></b></p>