use of following-sibling

A

apicard

I have a simple document like this:

<Accept>
<XXXX/>
<Token image="From"/>
<Date value="2007-01-01"/>
<Token image="To"/>
<Date value="2007-01-01"/>
</Accept>

where i want to get the date element following the to token. (from and
to are both optional, so it cannot be only position relative)

I am using the following query: "child::Token[fn:upper-
case(@image)='TO']/following-sibling::*"
but my problem is that it's always returning me the token and the date
element. I would have expected to only get the date element.

For now i changed it to: "child::Token[fn:upper-case(@image)='FROM']/
following-sibling::*[2]" and that works, but I feel like I am missing
something here.

Please help.
Thanks
Alain
 
J

Joe Kesselman

I am using the following query: "child::Token[fn:upper-
case(@image)='TO']/following-sibling::*"
but my problem is that it's always returning me the token and the date
element. I would have expected to only get the date element.

The following sibling axis returns all following siblings, unless you
specify which one you want -- by name, by position, or by some other
criterion.

If you want the single Date most closely following the FROM Token, try
"child::Token[fn:upper-case(@image)='FROM']/following-sibling::Date[1]"

XSLT is a programming language. If you're fuzzy about what you ask for,
you get back fuzzy results.
 
R

Richard Tobin

I am using the following query: "child::Token[fn:upper-
case(@image)='TO']/following-sibling::*"
but my problem is that it's always returning me the token and the date
element. I would have expected to only get the date element.
[/QUOTE]
The following sibling axis returns all following siblings, unless you
specify which one you want -- by name, by position, or by some other
criterion.

Yes, but given the OP's example:

<Accept>
<XXXX/>
<Token image="From"/>
<Date value="2007-01-01"/>
<Token image="To"/>
<Date value="2007-01-01"/>
</Accept>

the Token element with @image=To only has one following-sibling
element. His expression should therefore return only the final Date
element.

-- Richard
 
J

Joe Kesselman

Richard said:
Yes, but given the OP's example:

You're right, I was reading in a hurry, as well entangling his two
sketched soltuions. (Sorry; negotiating on a house and somewhat
distracted.) Lemme recheck...
<Accept>
<XXXX/>
<Token image="From"/>
<Date value="2007-01-01"/>
<Token image="To"/>
<Date value="2007-01-01"/>
</Accept>
>"child::Token[fn:upper- case(@image)='TO']/following-sibling::*"

In this particular example, that should return the second Date. If there
are any other elements following the "TO" token, they will also be
returned. Given the <XXXX/>, I presume this is a simplified example, and
thus I presume he'd be better off limiting it.

"child::Token[fn:upper- case(@image)='TO']/following-sibling::*[1]"
indeed ought to work, to return the first following sibling element.
(though I'd still suggest explicitly using "child::Token[fn:upper-
case(@image)='TO']/following-sibling::Date[1]")

His workaround, "child::Token[fn:upper-case(@image)='FROM']/
following-sibling::*[2]", SHOULDN'T work -- that should be returning the
"TO" token, not the date, assuming the description of the input is
correct. He claims it does work, which suggests that either the XPath
implementation he's using is broken or that the input isn't actually as
shown.

I may still be half-asleep and distracted and incoherent; apologies if
so... but there's something here I'm missing.


(This is why associated data should generally be grouped as
parent-child, or in a higher-level wrapper, or as attributes on a single
element, rather than counting on the order.)
 
A

apicard

Sorry I see a few inconsistencies in my example Like from instead of
to in the query.

But, first I learned that following sibling returns all the following
siblings, thanks.

But, my working example ""child::Token[fn:upper-case(@image)='TO']/
following-sibling::*[2]", is still problematic from what i understand
here, since the element Token with the selected attribute image of
"TO" shouldn't be selected as a sibling of itself and have to be
filtered. Am I getting this part right?

BTW, the reason that I am using a start after the following-sibling,
is that in the real world the next element following the from or to
token, can be one of about 4 different element names.

I am using Saxon as my XQuery processor.
 
R

Richard Tobin

I am using Saxon as my XQuery processor.

It would be useful if you could reproduce your example as a short XML
file and stylesheet that others can run. Then we can see if it's a bug
in Saxon.

-- Richard
 
M

Martin Honnen

But, my working example ""child::Token[fn:upper-case(@image)='TO']/
following-sibling::*[2]", is still problematic from what i understand
here, since the element Token with the selected attribute image of
"TO" shouldn't be selected as a sibling of itself and have to be
filtered. Am I getting this part right?

BTW, the reason that I am using a start after the following-sibling,
is that in the real world the next element following the from or to
token, can be one of about 4 different element names.

I am using Saxon as my XQuery processor.

With the XML being your original sample

<Accept>
<XXXX/>
<Token image="From"/>
<Date value="2007-01-01"/>
<Token image="To"/>
<Date value="2007-01-01"/>
</Accept>

and the XQuery expression being

/Accept/child::Token[fn:upper-case(@image)='TO']/following-sibling::*

Saxon 8.9 returns

<?xml version="1.0" encoding="UTF-8"?>
<Date value="2007-01-01"/>

for me which is only the Date element so it returns what you are looking
for.

I have run the Java version of Saxon from the command line.
 
J

Joseph Kesselman

"TO" shouldn't be selected as a sibling of itself and have to be
filtered. Am I getting this part right?

That's correct. It sounds like either you aren't running the code/data
you think you are, or there's a bug in the processor.
 
A

apicard

Well, thanks everyone for your help and my apologies about to Saxon.

We are running Saxon with a wrapper implementation that feeds it nodes
and items from an underlying object tree structure, instead of from
XML. We have been using this layer for over 2 years without problems,
but we are now starting to get more creative in our queries and have
uncovered found a bug in the list that iterateAxis() was returning for
following siblings.

Alain
 
J

Joseph Kesselman

uncovered found a bug in the list that iterateAxis() was returning for
following siblings.

Been there, done that, for a large portion of Xalan's internal DTM model
and adapters thereunto. <smile/>

(This is another reason we so often ask for runnable stand-alone
examples that will demonstrate the problem -- it's a good way to rule
out things other than the XPath/XSLT itself.)
 
P

Peter Flynn

Joe said:
I am using the following query: "child::Token[fn:upper-
case(@image)='TO']/following-sibling::*"
but my problem is that it's always returning me the token and the date
element. I would have expected to only get the date element.

The following sibling axis returns all following siblings, unless you
specify which one you want -- by name, by position, or by some other
criterion.

I think the OP's point was that in the example, there *is* only one
sibling element (Date) following the relevant Token element, and that
therefore following-sibling::* should only return one element.

If I run the user's example in Saxon, it does indeed only return Date.

///Peter
 
P

Peter Flynn

Sorry I see a few inconsistencies in my example Like from instead of
to in the query.

But, first I learned that following sibling returns all the following
siblings, thanks.

But, my working example ""child::Token[fn:upper-case(@image)='TO']/
following-sibling::*[2]", is still problematic from what i understand
here, since the element Token with the selected attribute image of
"TO" shouldn't be selected as a sibling of itself and have to be
filtered. Am I getting this part right?

BTW, the reason that I am using a start after the following-sibling,
is that in the real world the next element following the from or to
token, can be one of about 4 different element names.

I am using Saxon as my XQuery processor.
 
M

Monadear D

Hi everybody,

I am not able to use following::sibling properly.
My Xml file is as follows:-

<Changed>
<RcpUid>
<RwyUid>
<AhpUid>
<codeId>EHAM</codeId>
</AhpUid>
<txtDesig>06/24</txtDesig>
</RwyUid>
</RcpUid>
<Rcp>
<RcpUid>
<RwyUid>
<AhpUid>
<codeId>EHAM</codeId>
</AhpUid>
<txtDesig>06/24</txtDesig>
</RwyUid>
<geoLat>521720.87N</geoLat>
<geoLong>0044414.25E</geoLong>
</RcpUid>
</Rcp>

XSLT:-

<xsl:template match="Changed">
<xsl:variable name="Next-node"
select="following-sibling::Changed/child::node()[1]"/>
<xsl:choose>
<Changed>
<xsl:when test="substring(name(current()),4, 6) = 'Uid'">

<xsl:copy-of elect="current()"/>
<xsl:copy-of select= "$Next-node"/>
</Changed>
</Xsl:When>
</Xsl:Choose>

This logic returns me the correct output for two nodes but if there are
four nodes then Next-node is calling the same value.What i want is that
after incrementing the level it should also increment its value
according to level.

Can anybody help me for this
Thanks i advance.

</Changed>
 
P

Pavel Lepin

Monadear D said:
<Changed>
<RcpUid>
<RwyUid>
<AhpUid>
<codeId>EHAM</codeId>
</AhpUid>
<txtDesig>06/24</txtDesig>
</RwyUid>
</RcpUid>
<Rcp>
<RcpUid>
<RwyUid>
<AhpUid>
<codeId>EHAM</codeId>
</AhpUid>
<txtDesig>06/24</txtDesig>
</RwyUid>
<geoLat>521720.87N</geoLat>
<geoLong>0044414.25E</geoLong>
</RcpUid>
</Rcp>

Not well-formed.
<xsl:template match="Changed">
<xsl:variable name="Next-node"
select="following-sibling::Changed/child::node()[1]"/>
<xsl:choose>
<Changed>
<xsl:when test="substring(name(current()),4, 6) =
'Uid'">

<xsl:copy-of elect="current()"/>
<xsl:copy-of select= "$Next-node"/>
</Changed>
</Xsl:When>
</Xsl:Choose>

Not well-formed in more ways than I would care to mention.
Your source document isn't, either, but your Changed
element doesn't seem to have any Changed element siblings.
Well, it's hard to tell, with the document not being
well-formed, which is the whole point of people wanting
help normally posting well-formed examples, and
transformations that others can actually run in their
processors, instead of some random snippets that don't make
a whole lot of sense.
This logic returns me the correct output for two nodes but
if there are four nodes then Next-node is calling the same
value.

Either my English parser just broke, or your English
serializer did.
What i want is that after incrementing the level it
should also increment its value according to level.
What?

Can anybody help me for this

Nope. Oh wait, I think I can:

<http://www.catb.org/~esr/faqs/smart-questions.html>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,000
Messages
2,570,252
Members
46,848
Latest member
CristineKo

Latest Threads

Top