24

I am looking to find all attributes of an element that match a certain pattern.

So for an element

<element s2="1" name="aaaa" id="1" />
<element s3="1" name="aaaa" id="2" />

I would like to be able to find all attributes that start with 's' (returning the value of s1 for the first element and s3 for the value of the second element).

If this is outside of xpath's ability please let me know.

0

4 Answers 4

41

Use:

element/@*[starts-with(name(), 's')]

This XPath expression selects all atribute nodes whose name starts with the string 's' and that are attributes of elements named element that are children of the current node.

starts-with() is a standard function in XPath 1.0

Sign up to request clarification or add additional context in comments.

2 Comments

Works as advertised and helped me get the original answer working as well.
This was exactly what I was looking for! Thanks for the question and an answer. :)
4
element/@*[substring(name(), 1,1) = "s"]

will match any attribute that starts with 's'.

The function starts-with() might look better than using substring()

5 Comments

Hmmm using this in XMLSpy, which is my go-to application for Xpath I am getting an error "Unexpected token - "[substring(name(), 1,1) =".
This definitely looks like the approach I need so many thanks for the answer.
Thanks to Dimitrie the following substring pattern works also element/@*[substring(name(),1,1) = 's']
@Dunderklumpen: Actually, the XPath expression I came up with is: element/@*[starts-with(name(), 's')]
You need to correct your Expression -- right now it isn't syntactically valid.
3

I've tested the given answers from both @Dimitre-Novatchev and @Ledhund, using lxml.html module in Python.

Both element/@*[starts-with(name(), 's')] and element/@*[substring(name(), 1,1) = "s"] return only the values of s2 and s3. You won't be able to know which value belong to which attribute.

I think in practice I would be more interested in finding the elements themselves that contain the attributes of names starting with specific characters rather than just their values.

To achieve that is very simple, just add /.. at the end,

element/@*[starts-with(name(), "s")]/..

or

element/@*[starts-with(name(), "s")]/parent::*

or

element/@*[starts-with(name(), "s")]/parent::node()

Comments

0

None from above worked for me. So I did not some changes and it worked for me. :)

/*:UserCustomField[starts-with(@name, 'purchaseDate')]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.