| Author |
Is there a way to compare 2 xpaths in JSTL?
|
Benjamin Weaver
Ranch Hand
Joined: Apr 08, 2003
Posts: 161
|
|
In JSTL 1.1 on Tomcat 5.28, I want to test whether 2 xpath expressions are the same. Is there a way to do that? <x:if> can surely check whether a path exists, but I want the boolean to indicate whether one xpath is the same as another xpath. The point is to find out if a sibling element is of a certain tag type. For example, the following code <x:if select="$doc/ThisPath"> checks simply whether the path "$doc/ThisPath" exists But I want to find how to do something like this: <x:if select="[$doc/ThisPath == $doc/someParticularTag]"> Any help is appreciated!
|
 |
Paul Clapham
Bartender
Joined: Oct 14, 2005
Posts: 16483
|
|
|
Yes, but the compare-for-equals operator in XPath is just = and not ==.
|
 |
Paul Clapham
Bartender
Joined: Oct 14, 2005
Posts: 16483
|
|
|
Oh, and you don't need those square brackets either.
|
 |
Benjamin Weaver
Ranch Hand
Joined: Apr 08, 2003
Posts: 161
|
|
Thanks Hugh, I realise my question had a second part. Given the following code, <x:forEach var="linePart" select="following-sibling::*" > how would I reference the xpath of the variable linePart? A statement like <x ut select="$linePart" /> will reference the value inside the tag. But I want just the xpath TO the tag.
|
 |
Paul Clapham
Bartender
Joined: Oct 14, 2005
Posts: 16483
|
|
Actually now that I re-read your question I realize that I don't understand it very well. I don't understand what it means to say that two XPath expressions are "the same". It's quite possible for two XPath expressions that have different external representations to return the same nodesets. I was under the impression you just wanted to know whether two XPath expressions returned the same nodesets. And you're asking for "the" XPath to a node? Again, there's usually more than one way to represent that. There may be a specification that describes a canonical XPath representation for a node but if there is I'm not aware of it.
|
 |
Paul Clapham
Bartender
Joined: Oct 14, 2005
Posts: 16483
|
|
Maybe I should ignore most of the question and just concentrate on the real problem, which appears to be
The point is to find out if a sibling element is of a certain tag type.
I think you should just concentrate on figuring out an XPath expression which tells you that. For example if that means "Is there a following sibling which is an ABC element?" then your XPath would be "following-sibling::ABC" which would return either the ABC element or nothing. Or if it means "Is the next sibling an ABC element?" then your XPath would be something like "following-sibling::[1][local-name()='ABC']"... I say something like because I never get those things right the first time.
|
 |
Benjamin Weaver
Ranch Hand
Joined: Apr 08, 2003
Posts: 161
|
|
Thanks, Paul, Here's the xml (simplified). It's a spec I cannot change. <text> <lb n=1/> <w>someword</w> <w>someword</w> <w>someword</w> <lb n=2/> </text> ["lb" stands for "line break." We are putting up lines of text] The problem I face is that lb and word elements are siblings. To process all words in a given line it seems I have to do the following: (1) <x:forEach var="line" select="...path...text/lb"> (2)<x:forEach var="linePart" select="following-sibling::*" > [this will get ALL following siblings of the current line break down to the end of the text. But we want to exit the loop, stop processing word elements for a given line break once the NEXT LINE BREAK element is reached (in the example xml, lb n=2): I could have used a choose/when/otherwise, but didn't feel it necessary So the iteration I have written is below. The part I don't know how to write, where I determine whether the current sibling is in fact the next line break, is found in the first "if" statement after the foreach call. (2) expanded: <x:forEach var="linePart" select="following-sibling::*" > <c:set var="stillInThisLine" value="true" scope="page" /> <x:if select="COMPARE XPATH OF CURRENT LINEPART TO LINEPATH OF NEXT LB"> <c:set var="stillInThisLine" value="false" /> </x:if> <%--now test; if still in the current line, print out the word; otherwise don't do anything after the next lb element is reached. --%> <c:if test="$stillInThisLine"> <x ut select="$linePart" /> </c:if> </x:forEach>
|
 |
Benjamin Weaver
Ranch Hand
Joined: Apr 08, 2003
Posts: 161
|
|
Sorry, a paraphrase is easier, 1. After hitting a given line break element, I want to process only those words immediately following it. 2. FROM THE NEXT LINE BREAK ELEMENT (say lb n=2 AND FOREVER THEREAFTER, I WANT TO DO NOTHING. 3. then the outer foreach loop brings me to the next line, and steps 1 and 2 are repeated... Here is a better xml example: <text> <lb n=1 /> <w>someWord</w> <w>someWord</w> <w>someWord</w> <lb n=2 /> <w>someWord</w> <w>someWord</w> <lb n=3 /> <w>someWord</w> <w>someWord</w> </text>
|
 |
Benjamin Weaver
Ranch Hand
Joined: Apr 08, 2003
Posts: 161
|
|
Paul, thanks again. I have slept on this, and now it seems not so difficult a problem, using your solution. Your second guess was the correct one: my question to be answered: "is the next sibling an element of type "lb" (line break)?" So it seems I should loop through the words following each line break, testing each one with your call: following-sibling::[1][local-name()='w']"... As soon as I hit a following-sibling that is not a word but a line-break, indicating the next line of text, I exit the inner loop that processes the words and continue, in the outer loop to process the next line break. I will try it out.
|
 |
Paul Clapham
Bartender
Joined: Oct 14, 2005
Posts: 16483
|
|
In other words: FOR EACH line break element, Process the word elements up to the next line break element. That seems to be your latest approach, which I think is better than the earlier ones. In XSLT it's preferable to write declarative algorithms (e.g. "Here's what to do for a word element") rather than procedural algorithms (e.g. "Scan the word elements and if the next element is a line break then..."). That's just the way the language works.
|
 |
 |
|
|
subject: Is there a way to compare 2 xpaths in JSTL?
|
|
|