Or even this:
/*/BookTitle/Book
[index-of(/*/BookTitle/Book[1]/concat(Author,
'|',Title),
concat(Author, '|', Title)
)[2]
> 0
][1]"/>
which is more readable as:
/*/BookTitle/Book[index-of($vallAuthorTitle, concat(Author, '|', Title))[2]
0][1]
if we substitute $vallAuthorTitle for:
/*/BookTitle/Book[1]/concat(Author, '|',Title)
Certainly, if Xpath 3 were allowed, then one could use a "let" expression
for this substitution -- and then other, better solutions would be possible
using the simple mapping operator "!" and/or maps.
Something more about the technique used in these expressions can be found
here:
https://dnovatchev.wordpress.com/2008/11/16/xpath-2-0-gems-find-all-duplicate-values-in-a-sequence-part-2/
Cheers,
Dimitre
On Thu, May 2, 2019 at 9:20 AM Dimitre Novatchev
<dnovatchev(_at_)gmail(_dot_)com>
wrote:
Assuming that there is just one BookBinding for all books with the same
title by the same author and with the same binding, and also assuming that
all books with the same title by the same author are in ** contiguous**
bindings (which is the case with the provided document), then this XPath
2.0 expression selects the wanted Book elements. At least for me it seems
less complex and more understandable than the originally provided expression
"for $b in
/*/*/Book[Author = ../following-sibling::*[1]/Book/Author
and Title = ../following-sibling::*[1]/Book/Title
and not(Binding = ../following-sibling::*[1]/Book/Binding)
][1],
$binding in distinct-values(/*/*/Book[Author = $b/Author and Title
= $b/Title]/Binding)
return
/*/*/Book[Author = $b/Author and Title = $b/Title and Binding =
$binding][1]
On Thu, May 2, 2019 at 5:55 AM Costello, Roger L.
costello(_at_)mitre(_dot_)org <
xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> wrote:
Hello XPath experts!
At the bottom of this message is my XML document. I need an XPath 2.0
expression that returns the result of this query:
Are there any book titles with more than
one binding? If yes, then show the first book
for each binding.
For the below XML document, the query should return these two books:
<Book>
<Author>Sally Smith</Author>
<Title>XYZ</Title>
<Binding>hardcover</Binding>
<Count>1</Count>
<Description>lo lo lo ..</Description>
</Book>
<Book>
<Author>Sally Smith</Author>
<Title>XYZ</Title>
<Binding>softcover</Binding>
<Count>1</Count>
<Description>do do do ..</Description>
</Book>
Notice that the two books have the same author and title but different
binding (hardcover versus softcover).
This XPath 2.0 expression seems to work:
for $i in /Bookstore/BookTitle/Book[1],
$j in /Bookstore/BookTitle/Book[1] return
if (($i ne $j)
and ($i/Author eq $j/Author)
and ($i/Title eq $j/Title)
and ($i/Binding ne $j/Binding)
and ($i = $j/preceding::Book))
then ($i, $j)
else ()
That expression seems awfully complicated. Is there a simpler expression?
If there isn't a simpler expression, then do you see anything missing in
the expression (i.e., something that the expression doesn't take into
consideration)? /Roger
<Bookstore>
<BookTitle>
<Book>
<Author>John Doe</Author>
<Title>ABC</Title>
<Binding>hardcover</Binding>
<Count>1</Count>
<Description>da da da ..</Description>
</Book>
<Book>
<Author>John Doe</Author>
<Title>ABC</Title>
<Binding>hardcover</Binding>
<Count>2</Count>
<Description>za za za ..</Description>
</Book>
</BookTitle>
<BookTitle>
<Book>
<Author>John Doe</Author>
<Title>Foo</Title>
<Binding>softcover</Binding>
<Count>1</Count>
<Description>na na na ..</Description>
</Book>
</BookTitle>
<BookTitle>
<Book>
<Author>Sally Smith</Author>
<Title>XYZ</Title>
<Binding>hardcover</Binding>
<Count>1</Count>
<Description>lo lo lo ..</Description>
</Book>
<Book>
<Author>Sally Smith</Author>
<Title>XYZ</Title>
<Binding>hardcover</Binding>
<Count>2</Count>
<Description>ho ho ho ..</Description>
</Book>
</BookTitle>
<BookTitle>
<Book>
<Author>Sally Smith</Author>
<Title>XYZ</Title>
<Binding>softcover</Binding>
<Count>1</Count>
<Description>do do do ..</Description>
</Book>
</BookTitle>
</Bookstore>
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--