我希望在xsl中可以做的是以下内容,但不幸的是父/位置()无效。
XSL
<xsl:template match="li">
<bullet>
<xsl:apply-templates/>
</bullet>
<!-- if this is the last bullet AND there are no more "p" tags, output footer -->
<xsl:if test="count(ancestor::div/*) = parent/position()">
<footer/>
</xsl:if>
</xsl:template>
XML
<html>
<div>
<p>There is an x number of me</p>
<p>There is an x number of me</p>
<p>There is an x number of me</p>
<ul>
<li>list item</li>
<li>list item</li>
<li>list item</li>
<li>list item</li>
<li>list item</li>
</ul>
</div>
</html>
任何人都有任何想法如何从 WITHIN 我的模板匹配来解决这个问题?
谢谢!
答案 0 :(得分:5)
您可以通过计算其前面的兄弟节点来查找源节点中父节点的位置:
<xsl:variable name="parent-position"
select="count(../preceding-sibling::*) + 1"/>
如果您想确定父p
元素后面是否有ul
元素,您可以在不使用职位的情况下对其进行测试:
<xsl:if test="../following-sibling:p">...</xsl:test>
然而,正如Dimitre和Oliver所指出的那样,在处理父元素时添加页脚更符合XSLT的精神。此外,显示的XPath表达式仅关注原始源树中的顺序。如果您打算在处理之前过滤元素或使用xsl:sort
重新排序,这些路径将无法按预期工作,因为它们将查看原始排序并包括源树中的所有节点。
答案 1 :(得分:2)
在XSLT中执行此操作的好方法是:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="div">
<xsl:apply-templates/>
<footer/>
</xsl:template>
<xsl:template match="li">
<bullet>
<xsl:apply-templates/>
</bullet>
</xsl:template>
</xsl:stylesheet>
<footer/>
的匹配在匹配div
的模板末尾最为自然,并且无需尝试比较任何位置。
答案 2 :(得分:1)
试试这个:
<xsl:template match="li">
<bullet>
<xsl:apply-templates/>
</bullet>
<xsl:if test="position()=last() and not(../following-sibling::p)">
<footer/>
</xsl:if>
</xsl:template>
答案 3 :(得分:0)
如果我理解正确,你正在寻找最后的li
;这是一个li
,后面没有li
个元素。这可以这样测试:
<xsl:template match="li">
<bullet>
<xsl:apply-templates/>
</bullet>
<xsl:if test="not(following-sibling::li)">
<footer />
</xsl:if>
</xsl:template>
虽然在你给出它的情况下,在处理ul
的结尾时添加页脚似乎更符合XSLT的精神:
<xsl:template match="ul">
<ul>
<xsl:apply-templates/>
</ul>
<footer />
</xsl:template>
<xsl:template match="li">
<bullet>
<xsl:apply-templates/>
</bullet>
</xsl:template>