Reputation: 2241
My XML looks a bit like this:
<root>
<child1>
<grandchild1>{tagID1}<grandchild1/>
<grandchild2>{tag2}<grandchild2/>
</child1>
<child2>{newtag1}<child2/>
<root/>
I am looking to retrieve all elements whose text() is like "{*}" i.e. contains a string between 2 curlies, but am not too familiar with xpath.
I thought the xquery syntax would be something like
"//*[matches(., '{*}')]"
but that is failing with unknown method "-->matches(.<--"
I'd be grateful if someone could correct me please.
Upvotes: 2
Views: 2448
Reputation: 38434
The matches()
function is available to XPath 2.0, but your XPath engine probably only supports XPath 1.0.
If that is the case, you'll have to end up with something like this:
//*[./text()[starts-with(., '{') and substring(., string-length(.), 1)='}']]
It looks for
ANY ELEMENT
//*
THAT HAS A TEXT NODE
[./text() ]
WHICH STARTS WITH A '{'
[starts-with(., '{') ]
AND ENDS WITH A '}'
and substring(., string-length(.), 1)='}'
The substring()
function call does what you would expect of an ends-with()
function if there was any in XPath 1.0.
EDIT (to address OP's comment about starts-with()
not being found, either)
I haven't ever seen an XPath engine that doesn't know starts-with()
. If it at least recognizes the substring()
function, you can try the following workaround:
//*[./text()[substring(., 1, 1)='{' and substring(., string-length(.), 1)='}']]
which should do the same.
Upvotes: 4
Reputation: 16917
Your XPath looks correct, but the xml and regex are wrong.
The {} are special chars and have to be escaped with \. And a * can not be used alone. So the correct expression is (using text() instead of ., so it does not check the text of all descendants) :
//*[matches(text(), '\{.*\}')]
Although that function is only available in XPath 2 (and XQuery, since it is a superset), you could try the full name fn:matches
.
In the xml the closing slashes have to be on the other side:
<root>
<child1>
<grandchild1>{tagID1}</grandchild1>
<grandchild2>{tag2}</grandchild2>
</child1>
<child2>{newtag1}</child2>
</root>
Upvotes: 3