Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XPath: Match one of multiple children

Tags:

xml

xslt

xpath

I have a small application that searches publication citations. The citations are in XML and I pass parameters to XSLT through PHP to search by fields like instrument or author. The structure looks like this:

<publications>
    <paper>
        <authors>
            <author>James Smith</author>
            <author>Jane Doe</author>
        </authors>
        <year>2010</year>
        <title>Paper 1</title>
        (more children)
    </paper>
    (more papers)
</publications>

When I call my template in the XSLT, I use a predicate to pare down which papers are shown based on the search criteria. So if the parameter $author is set, for example, I do:

<xsl:apply-templates select="paper[contains(authors/author, $author)]" />

The problem: this works for the first author in "authors", but ignores the ones after that. So in the example above, searching for "Smith" would return this paper, but "Doe" returns nothing.

How can I format my expression to take all "author" elements into account?

like image 329
tkm256 Avatar asked Jul 06 '11 19:07

tkm256


1 Answers

The contains function expects a string as its first argument, not a set of nodes. With your expression the first result of authors/author is converted to a string and then passed to the function.

Instead, use a predicate that tests each of the author nodes independently:

<xsl:apply-templates select="paper[authors/author[contains(., $author)]]" />

See, for example, this explanation of Saxon's behavior:

  • http://saxon.sourceforge.net/saxon6.5.3/expressions.html#StringExpressions
like image 153
Wayne Avatar answered Sep 25 '22 23:09

Wayne