Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you do wildcard matches with XSLT?

Tags:

xml

xslt

If I have a source file like this:

<animal name="fred_monkey" />
<animal name="jim_banana" />
<animal name="joe_monkey" />

Can I do an XPATH expression in my stylesheet which selects only the animals with the string '_monkey' in their name?

e.g. wildcard match '*_monkey' ?

like image 908
Chris Huang-Leaver Avatar asked Oct 15 '10 12:10

Chris Huang-Leaver


1 Answers

Can I do an XPATH expression in my stylesheet which selects only the animals with the string '_monkey' in their name?

e.g. wildcard match '*_monkey' ?

This wildcard means a string ending with "_monkey", not a string containing "_monkey".

Use:

//animal[ends-with(@name, '_monkey')]

The above uses the standard XPath 2.0 function ends-with() and is thus available only in XSLT 2.0.

In XSLT 1.0 use the following XPath 1.0 expression:

//animal[substring(@name, string-length(@name) -6)='_monkey']

It isn't recommended to use the // abbreviation as this may result in inefficient evaluation. Use more specific chain of location tests whenever the structure of the XML document is known. For example, if the animal elements are all children of the top element of the XML document, then the following XPath (2.0 or 1.0, respectively) expressions might be more efficient:

/*/animal[ends-with(@name, '_monkey')]

and

/*/animal[substring(@name, string-length(@name) -6)='_monkey']

Depending on one's specific needs (e.g. you really meant "contains" and not "ends with"), the functions contains(), starts-with() and substring() may also be useful:

contains(someString, someTargetString)

starts-with(someString, someTargetString)

substring(someString, start-index, length) = someTargetString

Finally, the match attribute of <xsl:templates> doesn't need to contain an absolute XPath expression -- just a relative XPath expression that specifies enough context is recommended to be used.

Thus, the above used as match expressions will be something as:

<xsl:template match="animal[ends-with(@name, '_monkey')]">

and

<xsl:template match=
  "animal[substring(@name, string-length(@name) -6)='_monkey']">
like image 57
Dimitre Novatchev Avatar answered Oct 29 '22 10:10

Dimitre Novatchev