示例输入:
<body>
<ul>
<li>
<p>Some text with <b><i><span style="color:red">formatting</span></i></b></p>
</li>
</ul>
</body>
“内联”元素是b
、i
或span
假设上下文节点是示例中嵌套的span
元素。
如何在不经过包含p
元素的搜索的情况下获取所有祖先内联元素?
表达式ancestor-or-self::*[self::b | self::i | self::span]
实际上应该工作,因为不可能有包含‘块’级元素的祖先内联元素,例如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>
但是,我不确定是否有更好或“标准”的方法来解决这个问题。
注意:代码中的$pElem/parent::*
将始终返回元素,因为内联项必须有块元素容器,如p
、h1
等。此外,假设最初提供的$pElem
参数始终是内联元素。
发布于 2017-06-06 07:39:35
使用
<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>
以及关于块元素和内联元素的假设,您可以在match="span | b | i"
上下文中重写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>
https://stackoverflow.com/questions/44392770
复制相似问题