ChatGPT解决这个技术问题 Extra ChatGPT

XPath to return only elements containing the text, and not its parents

In this xml, I want to match, the element containing 'match' (random2 element)

<root>
 <random1>
  <random2>match</random2>
  <random3>nomatch</random3>
 </random1>
</root>

ok, so far I have:

//[re:test(.,'match','i')] (with re in the proper namespace)

this returns random2, random1 and root... I would like to get only "random2"

any ideas?

Are you looking to match if it contains the word anywhere in the text(e.g. "see if this will match the word"), or only elements that have a value equal to "match" (ignoring surrounding whitespace)?
it's not that relevant, either would work. The problem was mainly that it was returning it's parents as well

M
Mads Hansen

Do you want to find elements that contain "match", or that equal "match"?

This will find elements that have text nodes that equal 'match' (matches none of the elements because of leading and trailing whitespace in random2):

//*[text()='match']

This will find all elements that have text nodes that equal "match", after removing leading and trailing whitespace(matches random2):

//*[normalize-space(text())='match']

This will find all elements that contain 'match' in the text node value (matches random2 and random3):

//*[contains(text(),'match')]

This XPATH 2.0 solution uses the matches() function and a regex pattern that looks for text nodes that contain 'match' and begin at the start of the string(i.e. ^) or a word boundary (i.e. \W) and terminated by the end of the string (i.e. $) or a word boundary. The third parameter i evaluates the regex pattern case-insensitive. (matches random2)

//*[matches(text(),'(^|\W)match($|\W)','i')]

Your second statement is not true. Hint: take an element with more than one text nodes whose first text node doesn't contain "match".
Thanks @Dimitre. Updated it with something that should be more robust.
actually I want to run a specific query with regexp like '^ma(t|T).*' I can use the first one? //*[text()='^ma(t|T).*'] right?
If you want to use regex, then you would use something like the last example. Regex isn't supported in XSLT 1.0, so you will need an XSLT 2.0 stylesheet and XSLT 2.0 processor(like saxon) to use it.
I believe //*/text()[normalize-space(.)='match']/parent::* should be //*[normalize-space(text())='match'] or //*[normalize-space(./text())='match']
G
Gregoire

Try

//re:*[. ='match']