|
|
Rank: Newbie
Joined: 7/14/2009 Posts: 5 Location: Montreal, Canada
|
I have an XML document that has the following basic structure:
<section id="1"> <...> <...> </section> <section id="2"> <...> <...> </section> <section id="3"> <...> <...> </section> ...
Is there a way using XPath or XQuery to find all the nodes that are between a start id and an end id? For example, In my XSLT I want to use the following construct: document("docpath")//id("1-3") to load an entire section of the other document that is between the start and end nodes. Thanks in advance
|
|
Rank: Advanced Member
Joined: 9/9/2005 Posts: 483 Location: AT
|
Hello,
If I am understanding you correctly then something like this should do the trick:
//section[@id > 0 and @id < 4]//*
|
|
Rank: Newbie
Joined: 7/14/2009 Posts: 5 Location: Montreal, Canada
|
Thanks for the reply Paul.
I forgot to mention that the id's for the document are not necessarily sequential (or even necessarily integers for that matter. The id attribute is of type xs:id) So my document can look something like this:
<section id="1"> <...> <...> </section> <section id="2"> <...> <...> </section> <section id="5"> <...> <...> </section>
<section id="3"> <...> <...> </section>
This is due to the fact that users can modify the document. We really need to be able to find the nodes that are physically between the start node and the end node. (We have a system where we generate web pages based on these xml files. Sections of other documents can be viewed from within the current document in a kind of folding panel. The client would like to define these "include links" by defining a start and endpoint so that subsequent modifications to the document (ie: a new section being added) are included without having to modify the original link. Does that make sense?)
I don't know if this is even possible. The closest we have come is by passing a list of id's to the id function like so: id(1;2;5;3). This is close to what we want, but not exactly what we need.
thanks again.
|
|
Rank: Advanced Member
Joined: 12/13/2005 Posts: 2,856 Location: Mauritius
|
If I understand you properly you have an id for the first and last section and need to find all sections between them?
You can try to use position() function for this. For example, provided that the first section has id = 5 and last id = 3
some-parent-element/section[@id = 5]/position() gives you a position of the first section
some-parent-element/section[@id = 3]/position() of a second one
and then you use them to filter all sections within (by using variables or directly using statements above)
some-parent-element/section[position()>= $from and position() <= $till]
|
|
Rank: Newbie
Joined: 7/14/2009 Posts: 5 Location: Montreal, Canada
|
vlad wrote:If I understand you properly you have an id for the first and last section and need to find all sections between them?
You can try to use position() function for this. For example, provided that the first section has id = 5 and last id = 3
some-parent-element/section[@id = 5]/position() gives you a position of the first section
some-parent-element/section[@id = 3]/position() of a second one
and then you use them to filter all sections within (by using variables or directly using statements above)
some-parent-element/section[position()>= $from and position() <= $till]
Thanks for the response Vlad, and sorry for the delay in responding. This solution looks like it could work. I did find another solution that worked for us as well. In essence, we did something like this:
([@SectionId]=$From]/following-sibling::element()) intersect ([@SectionId]=$To]/preceding-sibling::element())
So we generated a node set from the start element and all its following siblings and another node set from the end element and all its preceding siblings. Then we used the intersect function to give us the correct node set. (I simplified the XPath above for clarity. You need to add the start and end nodes to either side of the intersect to have them included.)
|
|
Rank: Advanced Member
Joined: 6/10/2007 Posts: 36
|
There are also the operators << and >> in XPath 2.0 that you can use as they can be applied to nodes to check whether one is before or after another:
Code:<xsl:variable name="s1" select="//section[@SectionId = $From]"/> <xsl:variable name="s2" select="//section[@SectionId = $To]"/> <xsl:variable name="sections" select="//section[. is $s1 or . is $s2 or ($s1 << . and . << $s2)]"/>
|
|
|
guest |