Help | Site Map
Connecting Tech Pros Worldwide
 
 
LinkBack Thread Tools
  #1  
Old July 20th, 2005, 09:40 AM
Michael
Guest
 
Posts: n/a
Default XPath Relational Query

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.

  #2  
Old July 20th, 2005, 09:40 AM
mukul_gandhi@yahoo.com
Guest
 
Posts: n/a
Default Re: XPath Relational Query

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

  #3  
Old July 20th, 2005, 09:40 AM
Michael
Guest
 
Posts: n/a
Default Re: XPath Relational Query

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.

  #4  
Old July 20th, 2005, 09:40 AM
mukul_gandhi@yahoo.com
Guest
 
Posts: n/a
Default Re: XPath Relational Query

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

Regards,
Mukul

Michael wrote:[color=blue]
> 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.[/color]

  #5  
Old July 20th, 2005, 09:40 AM
David Carlisle
Guest
 
Posts: n/a
Default Re: XPath Relational Query

"Michael" <mbnews@gmail.com> writes:
[color=blue]
> 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.[/color]

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

David
  #6  
Old July 20th, 2005, 09:40 AM
Michael
Guest
 
Posts: n/a
Default Re: XPath Relational Query

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

  #7  
Old July 20th, 2005, 09:40 AM
David Carlisle
Guest
 
Posts: n/a
Default Re: XPath Relational Query

"Michael" <mbnews@gmail.com> writes:
[color=blue]
> 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[/color]

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
 

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over network members.
Post your question now . . .
It's fast and it's free

Popular Articles