使用 XSLT / XPath 查找元素在其父元素中的位置
除了重写大量 XSLT 代码(我不会这样做)之外,当上下文任意设置为其他内容时,是否有办法找到元素在其父元素中的位置?下面是一个示例:
<!-- Here are my records-->
<xsl:for-each select="/path/to/record">
<xsl:variable name="record" select="."/>
<!-- At this point, I could use position() -->
<!-- Set the context to the current record -->
<xsl:for-each select="$record">
<!-- At this point, position() is meaningless because it's always 1 -->
<xsl:call-template name="SomeTemplate"/>
</xsl:for-each>
</xsl:for-each>
<!-- This template expects the current context being set to a record -->
<xsl:template name="SomeTemplate">
<!-- it does stuff with the record's fields -->
<xsl:value-of select="SomeRecordField"/>
<!-- How to access the record's position in /path/to or in any other path? -->
</xsl:template>
注意:这是一个简化的示例。我有几个限制使我无法实现明显的解决方案,例如将新参数传递给 SomeTemplate
等。我实际上只能修改 SomeTemplate
的内部。
注意:我将 Xalan 2.7.1 与 EXSLT 结合使用。那么这些技巧是可用的
有什么想法吗?
Apart from rewriting a lot of XSLT code (which I'm not going to do), is there a way to find the position of an element within its parent, when the context is arbitrarily set to something else? Here's an example:
<!-- Here are my records-->
<xsl:for-each select="/path/to/record">
<xsl:variable name="record" select="."/>
<!-- At this point, I could use position() -->
<!-- Set the context to the current record -->
<xsl:for-each select="$record">
<!-- At this point, position() is meaningless because it's always 1 -->
<xsl:call-template name="SomeTemplate"/>
</xsl:for-each>
</xsl:for-each>
<!-- This template expects the current context being set to a record -->
<xsl:template name="SomeTemplate">
<!-- it does stuff with the record's fields -->
<xsl:value-of select="SomeRecordField"/>
<!-- How to access the record's position in /path/to or in any other path? -->
</xsl:template>
NOTE: This is a simplified example. I have several constraints keeping me from implementing obvious solutions, such as passing new parameters to SomeTemplate
, etc. I can really only modify the internals of SomeTemplate
.
NOTE: I'm using Xalan 2.7.1 with EXSLT. So those tricks are available
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以使用
,甚至一般来说,
当然,如果您处理不统一的节点列表,则这种方法将不起作用,即:
在这种情况下,位置信息会丢失,除非将其存储在一个变量并将其传递给被调用的模板:
但显然这意味着一些代码重写,我意识到你想避免这种情况。
最后提示:
position()
不会告诉您节点在其父节点中的位置。它告诉您当前节点相对于您现在正在处理的节点列表的位置。如果您仅处理(即“将模板应用于”或“循环”)一个父节点内的节点,则这恰好是同一件事。如果你不这样做,那就不是。
最后提示#2:这
与此等效:
但后者的工作不会破坏
position()
的含义。调用模板不会更改上下文,因此.
将引用被调用模板中的正确节点。You could use
or even, generically,
Of course this approach will not work if you process a list of nodes that is not uniform, i.e.:
Position information is lost in such a case, unless you store it in a variable and pass that to the called template:
but obviously that would mean some code rewriting, which I realize you want to avoid.
Final hint:
position()
does not tell you the position of the node within its parent. It tells you the position of the current node relative to the list of nodes you are processing right now.If you only process (i.e. "apply templates to" or "loop over") nodes within one parent, this happens to be the same thing. If you don't, it's not.
Final hint #2: This
is is equivalent to this:
but the latter works without destroying the meaning of
position()
. Calling a template does not change context, so.
will refer to the correct node withing the called template.