[ACCEPTED]-Working With Nested XPath Predicates ... Refined-xpath
Generally you should avoid using //
where 10 you can. I'd consider rephrasing:
//object[../properties/@refObjectId=@objectId]
In the 9 expression provided, your nested predicate 8 is actually checking for
//properties/@refObjectId=//properties/@objectId
of which there 7 are none.
I hope this helps!
EDIT: Since the 6 question has been updated here is an updated 5 response: You added "It seems the @objectId 4 in the nested predicate does not refer to 3 the objectId attribute of the object node." You're 2 absolutely right! So let's fix it!!
//object[../properties[not(@refPropertyId)]/@refObjectId=@objectId]
This 1 should be closer to what you're after!
Try this:
//objects[object/@objectId = properties/@refObjectId]/object
0
This should work:
//objects/object[@objectId = ../properties/@refObjectId]
I am not sure how your 7 xml is. However, if it is in the following 6 format:
<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>
Then you should use the following 5 xpath to get only objects 1111 and 7111. The 4 result should not include 4111 because the 3 properties where refObjectId = 4111 does 2 not immediately follow the object whose 1 objectId=4111.
//objects/properties[@refObjectId = preceding::object[1]/@objectId]/preceding::object[1]
Assuming that all <properties>
nodes that belong to 6 a given <object>
actually follow that object (your input 5 seems to imply that), you could do:
/objects/properties[
@refObjectId = preceding-sibling::object[1]/@objectId
and
not(@refPropertyId)
]/preceding-sibling::object[1]
This 4 should perform pretty well.
If you happen 3 to be in XSLT, things get a lot simpler:
<xsl:key name="kPropertiesByObjectId" match="properties" use="@refObjectId" />
and 2
<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>
In the XSLT case, the order of object and 1 proerties nodes becomes irrelevant.
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.