By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,156 Members | 1,047 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,156 IT Pros & Developers. It's quick & easy.

XPath Relational Query

P: n/a
To all,

I am trying to query an XML document of the following structure.

<ROOT>
<A>
<B id="1"/>
<B id="2"/>
<B id="3"/>
</A>
<A>
<C id="1"/>
<C id="2"/>
<C id="5"/>
<C id="6"/>
</A>
</ROOT>

I want to select all <C> nodes that do not have a <B> element
associated (by id). In other words, what i am looking for is <C
id="5"/> and <C id="6"/>. I realize XPath was not designed to perform
such queries but is there any way to accomplish this?

What I have in mind is something like this:

//C[count(//B[@id = @id]) = 0]

The first "@id" is referencing the "id" attribute of the <B> element. I
want the second "@id" to reference the "id" attribute of the <C>
element. I can't think of any way to do this with axis since they only
allow me to choose nodes relative to the current node which is B.

Thanks,
Michael B.

Jul 20 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Please try this XSL ..

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

<xsl:output method="xml" encoding="UTF-8" indent="yes" />

<xsl:template match="/ROOT">
<result>
<xsl:for-each select=".//C">
<xsl:if test="not(@id = preceding::B/@id)">
<xsl:copy-of select="." />
</xsl:if>
</xsl:for-each>
</result>
</xsl:template>

</xsl:stylesheet>

Regards,
Mukul

Jul 20 '05 #2

P: n/a
Thanks Mukul,

I cannot use XSL. I am actually using an XmlDocument object as the
internal data structure for a windows .net application, I need to pick
nodes using XPath only. My other option is to write code to perform
this logic, but i was looking for a way to do this with XPath alone.

Thank you for your help.

Regards,
Michael B.

Jul 20 '05 #3

P: n/a
The XslTransform class of .NET framework allows to do XSLT (1.0)
transformation .. I guess it should help ..

Regards,
Mukul

Michael wrote:
Thanks Mukul,

I cannot use XSL. I am actually using an XmlDocument object as the
internal data structure for a windows .net application, I need to pick
nodes using XPath only. My other option is to write code to perform
this logic, but i was looking for a way to do this with XPath alone.

Thank you for your help.

Regards,
Michael B.


Jul 20 '05 #4

P: n/a
"Michael" <mb****@gmail.com> writes:
To all,

I am trying to query an XML document of the following structure.

<ROOT>
<A>
<B id="1"/>
<B id="2"/>
<B id="3"/>
</A>
<A>
<C id="1"/>
<C id="2"/>
<C id="5"/>
<C id="6"/>
</A>
</ROOT>

I want to select all <C> nodes that do not have a <B> element
associated (by id). In other words, what i am looking for is <C
id="5"/> and <C id="6"/>. I realize XPath was not designed to perform
such queries but is there any way to accomplish this?

What I have in mind is something like this:

//C[count(//B[@id = @id]) = 0]

The first "@id" is referencing the "id" attribute of the <B> element. I
want the second "@id" to reference the "id" attribute of the <C>
element. I can't think of any way to do this with axis since they only
allow me to choose nodes relative to the current node which is B.

Thanks,
Michael B.


//C[not(@id=//B/@id)]

David
Jul 20 '05 #5

P: n/a
Thanks a lot David, that did it.

Do you have any idea how the XPath processor executes this? Does it
execute //B/@id every time the <C> element is found or does it do it
only once and then checks the @id of <C> against that result set.

Thanks,
Michael

Jul 20 '05 #6

P: n/a
"Michael" <mb****@gmail.com> writes:
Thanks a lot David, that did it.

Do you have any idea how the XPath processor executes this? Does it
execute //B/@id every time the <C> element is found or does it do it
only once and then checks the @id of <C> against that result set.

Thanks,
Michael


one or the other:-)
it depends on the processor, some do take common expressions out of
loops and probably some don't. I think saxon does, for example.
Most XPath API presumably allow you to declare xpath variables
in which case you could give your processor a hint and stick //B/@id in
a variable and use a variable reference in the predicate, but if your
processor is doing that anyway that will make no difference.

It's not entirely trival for an optimiser to take an expression such as
//B/@id out of a loop as it's not a constant expression, the value of /
and hence the value of //B/@id depends on the document in which the
current current node sits. In this case all the nodes are necessarily in
the same docuument (as they are selected with //C) but in general this
can get tricky.

David
Jul 20 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.