XSL:如何测试当前节点是否是另一个节点的后代
我对 XSLT 还很陌生,但目前需要将它用于 CMS。我已经提出了一个问题,但我将尝试描述我的问题,但不会涉及太多有关底层 CMS 的信息。如果您需要更多上下文来帮助我,我可以将其添加进去。
所以我想做的就是测试 xml 的节点是否是特定节点的后代。
<xsl:if test="$currentNode::IsADescendantOf($someNode)">
Write this out.
</xsl:if>
有人有什么想法吗?
提前致谢 :)
I'm pretty new to XSLT, but need to use it for a CMS using at the moment. I've already come up with a problem, but I'll try to describe my it without going into too much information about the underlying CMS. If you need more context to help me, I can add it in.
So all I want to do is test if a node of my xml is a descendant of a particular node.
<xsl:if test="$currentNode::IsADescendantOf($someNode)">
Write this out.
</xsl:if>
Any ideas anyone?
Thanks in advance :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您应该使用联合操作和节点集大小比较:
如果 $someNode 是 $currentNode 的祖先,则 $someNode|$currentNode/ancestor::* 将返回相同的值节点集为 $currentNode/ancestor::* (节点集没有任何双倍隆)。
如果不是,则由于并集,第一个节点集将比第二个节点集多一个节点。
You should use union operation and node-set size comparison:
If $someNode is an ancestor of $currentNode, $someNode|$currentNode/ancestor::* will return the same node-set as $currentNode/ancestor::* (node-set don't have any doublons).
If not, the first node-set will have one more node than the second because of the union.
一个可移植的(XPath 1.0 和 2.0)解决方案是:
沿着祖先轴向上走并检查其中的每个元素。如果(且仅当)祖先之一的唯一 ID 与
$someNode
的唯一 ID 匹配时,生成的节点集不为空。非空节点集的计算结果为 true,因此满足条件。
测试 - 查找所有
是
的后代:并且
结果为
注意,如果您指的是实际当前节点,就像我在 for-each 中所做的那样,不需要单独的
$currentNode
变量。默认情况下,所有 XPath 都是相对于当前节点的。一种变体是自上而下的方式。但效率较低(可能低几个数量级):
A portable (XPath 1.0 and 2.0) solution would be:
This walks up the ancestor axis and checks every element in it. If (and only if) the unique ID of one of the ancestors matches the unique ID of
$someNode
, the resulting node-set is not empty.Non-empty node-sets evaluate to true, so the condition is fulfilled.
Test - find all
<baz>
that are descendant of<foo>
:and
results in
Note that if you are referring to the actual current node, like I do in the for-each, there is no need for a separate
$currentNode
variable. All XPath is relative to the current node by default.A variant would be the top-down way. It is less efficient though (probably by several orders of magnitude):
答案很简单,
您所要做的就是:
...然后添加其余的
逻辑是,如果该节点是某个节点的后代,那么它将拥有一个或多个该节点。
The answer is quite easy,
all you have to do is:
... then add the rest
the logic is that if the node is a descendant of somenode, then it will have one or more of that node.
查看 XSL/XPath 参考中的“祖先”轴
编辑:我正在与您一起学习。看看这是否有效(我希望我的 XSL 调试器在此系统上可用:-)
Look at the "ancestor" axis in your XSL/XPath reference
EDIT: I'm learning along with you. See if this works (I wish I had my XSL debugger available on this system :-)
后代检查
最好的方法是使用后代::* 轴。
如果您有一段如下所示的 XML,并且想要匹配第一个
节点的后代节点。
XML
XSLT
祖先检查
这可能在大多数情况下都有效。
。
如果您有多个节点要比较并且需要确保它是节点匹配而不是名称匹配,则您可以使用generate-id()
IMO 比较运算符在比较祖先时不能使用,因为它需要叶节点,而叶节点没有后代。
但我建议使用后代::* 轴,因为它更具可读性和灵活性。
Descendant checking
The best way would be to use the descendant::* axis.
If you have a piece of XML looking like this and want to match the descendant
<a>
nodes from the first<alpha>
node.XML
XSLT
Ancestor checking
This would probably work in most cases.
Where
Or you can just use generate-id() if you have multiple nodes to compare against and need to make sure that it is a node match and not a name match.
The
is
comparison operator cannot IMO be used when comparing ancestors since it requires a leaf node, and leaf nodes do not have descendants.But i'd recommend using the descendant::* axis since it's much more readable and flexible.