我想编写一个xsl模板,它检查给定节点是否是唯一的子节点,而不是某些指定的元素:
在此示例中,<target />将更改为<hit />,因为它是唯一的<target />节点,并且只有<ok />节点位于其前面
<root>
<!-- this is ok, the ok nodes are at the top, followed by only 1 target -->
<mynode>
<ok1/>
<ok2/>
<target/>
</mynode>
<!-- will fail, bad element before target -->
<mynode>
<ok1/>
<ok2/>
<bad/>
<target/>
</mynode>
<!-- no match, multiple target nodes -->
<mynode>
<ok1/>
<ok2/>
<target/>
<target/>
</mynode>
</root>
我正在使用这个xpath:
<xsl:template match="target[not(following-sibling::*)]
[not(preceding-sibling::target)]
[not(preceding-sibling::*[starts-with(name(), 'bad' or 'hello')])]
">
<hit>
<xsl:apply-templates/>
</hit>
</xsl:template>
在最后一个谓词中,我是否必须明确指出我不想要的任何节点?我可以喜欢吗?
not(preceding-sibling::*[not(starts-with(name(), 'ok'))])
谢谢
2 回答
这个怎么样:
解释是匹配
target
如果:其父级的所有子元素的数量等于
其父级的所有好子元素的数量加一(本身)
Edit 如果您只想匹配元素,如果它是其父项的最后一个子项(您的问题中没有这样说,但是您的示例提示),您可以将
and not(following-sibling::*)
添加到上面的谓词中,或者这是另一种方法:但你似乎已经想到了自己的一个 .
Lastly, 如果您真正想要做的是允许某些特定的OK元素并且不匹配基于前缀的名称,则可以使用
self::
:将不会工作'坏'或'你好'是布尔值或字符串你也不需要使用双not()而只是做
您还可以创建白名单或黑名单,并使用contains()XPath函数对其进行迭代,例如:
然后匹配