所有好的答案!但问题值得改进......
我有以下示例XML ...
<objects>
<object objectId="1123" ... />
<properties refObjectId="1123" ... />
<properties refObjectId="1123" refPropertyId="2311" ... />
<properties refObjectId="1123" refPropertyId="4611" ... />
<object objectId="2123" ... />
<properties refObjectId="2123" refPropertyId="4311" ... />
<properties refObjectId="2123" refPropertyId="8611" ... />
....
</objects>
...以及以下XPath查询...
//object[//properties[@refObjectId=@objectId and not(@refPropertyId)]]
我认为此查询将返回所有object
个节点,其中properties
节点的refObjectId
属性等于objectId
object
属性} node 并且没有'refPropertyId'属性...即仅对象1123,而不是对象2123 ...但它没有。似乎嵌套谓词中的@objectId
未引用objectId
节点的object
属性。
有什么想法吗?我知道XML结构没有像你期望的那样嵌套,但是这种结构有原因。
答案 0 :(得分:7)
通常,您应该尽可能避免使用//
。我会考虑改写:
//object[../properties/@refObjectId=@objectId]
在提供的表达式中,嵌套谓词实际上是在检查
//properties/@refObjectId=//properties/@objectId
其中没有。
我希望这有帮助!
编辑:由于问题已在此处更新,因此更新后的回复: 您添加了“似乎嵌套谓词中的@objectId不引用对象节点的objectId属性。”你是绝对正确的!所以让我们解决它!!
//object[../properties[not(@refPropertyId)]/@refObjectId=@objectId]
这应该更接近你所追求的目标!
答案 1 :(得分:0)
试试这个:
//objects[object/@objectId = properties/@refObjectId]/object
答案 2 :(得分:0)
这应该有效:
//objects/object[@objectId = ../properties/@refObjectId]
我不确定你的xml是怎么回事。但是,如果它采用以下格式:
<objects>
<object objectId="1111" />
<properties refObjectId="1111" />
<object objectId="2111" />
<properties refObjectId="3111" />
<object objectId="4111" />
<properties refObjectId="5111" />
<object objectId="6111" />
<properties refObjectId="4111" />
<object objectId="7111" />
<properties refObjectId="7111" />
</objects>
然后你应该使用下面的xpath来获取对象1111和7111.结果不应该包括4111,因为refObjectId = 4111的属性不会紧跟在objectId = 4111的对象之后。
//objects/properties[@refObjectId = preceding::object[1]/@objectId]/preceding::object[1]
答案 3 :(得分:0)
假设属于给定<properties>
的所有<object>
个节点实际上跟随该对象(您的输入似乎暗示了这一点),您可以这样做:
/objects/properties[
@refObjectId = preceding-sibling::object[1]/@objectId
and
not(@refPropertyId)
]/preceding-sibling::object[1]
这应该表现得很好。
如果您碰巧在XSLT中,事情会变得更简单:
<xsl:key name="kPropertiesByObjectId" match="properties" use="@refObjectId" />
和
<xsl:template match="object">
<!-- This tests for an empty node-set. Non-empty node sets can only happen
for objects with at least one <properties> node without @refPropertyId -->
<xsl:if test="key('kPropertiesByObjectId', @objectId)[not(@refPropertyId)]">
<xsl:copy-of select="." />
</xsl:if>
</xsl:template>
在XSLT情况下,对象和proerties节点的顺序变得无关紧要。