Chr*_*ina 5 xslt predicate xslt-2.0
我在确定节点集的正确上下文时遇到了一些麻烦.我有一个看起来有点像这样的模板匹配(使用XSL 2.0):
<xsl:template match="//chapter/body/*[matches(name(), '^toc')][crossref][not(crossref/@idref='cip' or crossref/@idref='copy')]">
<xsl:variable name="curr_id" select="crossref/@idref"/>
<xsl:element name="location">
<xsl:attribute name="id"><xsl:value-of select="$curr_id"/></xsl:attribute>
<xsl:attribute name="order"><xsl:value-of select="position()"/></xsl:attribute>
<xsl:element name="label">
<text><xsl:value-of select="."/></text>
</xsl:element>
</xsl:element>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
XML看起来有点像这样:
<chapter id="toc">
<body>
<title>Contents</title>
<tocfm><crossref idref="cip">Catalog</crossref></tocfm>
<tocfm><crossref idref="copy">Copyright</crossref></tocfm>
<tocfm><crossref idref="ded">Dedication</crossref></tocfm>
<toc><crossref idref="prologue">Prologue</crossref></toc>
<toc><crossref idref="pt1">Book One</crossref></toc>
<toc><crossref idref="pt2">Book Two</crossref></toc>
<toc><crossref idref="pt3">Book Three</crossref></toc>
</body>
</chapter>
Run Code Online (Sandbox Code Playgroud)
我的期望是谓词将生成一个包含以下内容的节点集:
<tocfm><crossref idref="ded">Dedication</crossref></tocfm>
<toc><crossref idref="prologue">Prologue</crossref></toc>
<toc><crossref idref="pt1">Book One</crossref></toc>
<toc><crossref idref="pt2">Book Two</crossref></toc>
<toc><crossref idref="pt3">Book Three</crossref></toc>
Run Code Online (Sandbox Code Playgroud)
换句话说,所有包含crossref的toc类元素,其idref不是cip或copy.模板在输出方面执行此操作,但位置函数似乎不在该节点集上.相反,它为奉献产生了一个'3'的位置.但是,如果我输出通过跟随[1]的谓词找到的节点的值,我会得到Dedication作为该值.所以,我对于正在发挥作用的立场感到难过.任何人都可以开导我吗?
您的期望是错误的,因为它基于对如何定义上下文序列的常见误解.上下文序列不是由模板匹配模式决定的,而是由模板之外的东西决定的.
在某些时候,使用select表达式调用xsl:apply-templates.评估此表达式以生成项序列.将当前上下文序列推送到堆栈上.该项目序列成为上下文序列.上下文序列按顺序迭代.在访问每个项目时,此项目成为上下文项目,position()函数反映上下文序列中上下文项目的位置.此时,根据匹配表达式和优先级找到适当的模板.匹配表达式不返回序列.它们只是对上下文项的布尔测试 - 上下文项与模板规则匹配,或者不是.如果匹配且具有最高优先级,则输入模板序列构造函数.此时,上下文序列,上下文项和位置()都由客户端xsl:apply-templates定义,而不是由匹配条件定义.退出序列构造函数后,控件返回客户端xsl:apply-templates.它将增加position()数,更新上下文项,并再次找到适当的模板.这可以是与前一项相同的模板或不同的模板.
此样式表说明了它是确定上下文序列和位置()的客户端指令(apply-templates,for-each等),而不是模板匹配模式.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<t>
<note message ="apply-templates on EVEN items">
<xsl:apply-templates select="*/item[ (@id mod 2) = 0]"/>
</note>
<note message ="apply-templates on ODD items">
<xsl:apply-templates select="*/item[ (@id mod 2) = 1]">
<xsl:sort select="position()" data-type="number" order="descending"/>
</xsl:apply-templates>
</note>
</t>
</xsl:template>
<xsl:template match="item[@colour='blue']">
<note message='Brought to you by the Blue template!' positon="{position()}">
<xsl:copy-of select='self::*'/>
</note>
</xsl:template>
<xsl:template match="item[@colour='red']">
<note message='Brought to you by the Red template!' positon="{position()}">
<xsl:copy-of select='self::*'/>
</note>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
...适用于此文件......
<t>
<item id="1" colour="blue" />
<item id="2" colour="blue" />
<item id="3" colour="blue" />
<item id="4" colour="red" />
<item id="5" colour="red" />
<item id="6" colour="red" />
</t>
Run Code Online (Sandbox Code Playgroud)
......产生这个输出......
<t>
<note message="apply-templates on EVEN items">
<note message="Brought to you by the Blue template!" positon="1">
<item id="2" colour="blue" />
</note>
<note message="Brought to you by the Red template!" positon="2">
<item id="4" colour="red" />
</note>
<note message="Brought to you by the Red template!" positon="3">
<item id="6" colour="red" />
</note>
</note>
<note message="apply-templates on ODD items">
<note message="Brought to you by the Red template!" positon="1">
<item id="5" colour="red" />
</note>
<note message="Brought to you by the Blue template!" positon="2">
<item id="3" colour="blue" />
</note>
<note message="Brought to you by the Blue template!" positon="3">
<item id="1" colour="blue" />
</note>
</note>
</t>
Run Code Online (Sandbox Code Playgroud)