XPath wildcards on node name
Solution 1
This is the correct XPath 1.0 expression which selects an element with the last 5 character of name equal to "_cost" in any namespace.
/data/stats/*[substring(name(), string-length(name()) - 4) = '_cost']
Solution 2
With XPath 1.0 you can use /data/stats/*[substring-after(name(), '_cost') = '']
pattern. That checks if the element's name ends with the _cost
suffix.
In XPath 2.0 there is fn:ends-with(str, str)
and your corresponding expression will be *[ends-with(name(), '_cost')]
.
Solution 3
You could also use contains
e.g
/data/stats[contains(.,'_cost')]
Solution 4
The above did not work for me. I had to "slightly" modify that as follows:
/data/stats/*[contains(name(),'_cost')]
Related videos on Youtube
Ben Everard
I'm Ben, co-founder and developer at The Idea Bureau.
Updated on August 29, 2020Comments
-
Ben Everard almost 4 years
I want to grab a node from my XML file, the node has a prefix such as "latest_", but this may change and I'm keen for my XSLT to be as fluid as possible. Here's the XPath I want to use:
/data/stats/*_cost
This should match
latest_cost
,newest_cost
,anything_cost
, is there a way of doing this?Cheers :-)
-
Younes over 13 yearsDepends on if XPath 2.0 is available in your environment. XPath 1.0 doesn't allow this and 2.0 does.
-
Alex Nikolaenkov over 13 yearsAs for expressions like
*_cost
neither XPath 1.0 nor XPath 2.0 allows them.
-
-
Alex Nikolaenkov over 13 years
.
stands for all text content and this expression will match all thestats
nodes which text content contains_const
substring. No guarantees about postion and node names. -
Ben Everard over 13 yearsI went with this in the end
[contains(local-name(),'_cost')]
, it doesn't discriminate against position which is a shame, but in the context of its use that doesn't really matter. -
Ben Everard over 13 yearsThanks for your answer, contains worked well for me as it checked if the string exists as well. Also my environment doesn't appear to have XPath 2. Cheers anyway :-)
-
Admin over 13 yearsas @ILMV points out, this will select an element without "_cost" in its name. Check my answer.
-
Admin over 13 yearsThis is wrong. This selects a
stats
element cointaining "_cost" in its string value. Check my answer. -
Ben Everard over 13 yearsFair point, I've input this into my application and it does what I need it to without the other disadvantages, see my comment to reqsquare. Thanks.
-
halfer over 12 years+1 and thanks to @user357812 - this has been very helpful to my similar use case (matching attribute suffixes). How to do this is here if anyone is interested.
-
kletnoe almost 11 years[substring-after(name(), '_cost') = ''] This is also true for any name() that does not contain '_cost', -1
-
Si8 over 8 yearsI tried this:
<xsl:for-each select="substring(name(.), string-length(name(.)) - 1) = 'grp'">
I get the error: ` XPTY0020: Required item type of the context item for the child axis is node(); supplied value has item type xs:boolean` -
Dalmazio about 6 yearsFor completeness, what if the user wants to search for a prefix 'cost_' instead of suffix? How would the above XPath 1.0 expression change? I'm guessing:
/data/stats/*[substring(name(), 4) = 'cost_']