2

I have this div:

<div class="product-name">Product1</div>

I also have this div:

<div class="product-name gold">Product2</div>

How can I alter this xpath query to get whatever divs which contains product-name? Instead of getting an exact match.

/html/body//div[@class='product-name']

I googled it, but all I could find is how to use contains when searching for a value within a node, and not an attribute.

EDIT enter image description here

5
  • please provide your source document. Commented Mar 14, 2011 at 21:45
  • @Alex, why do you need to see any source other than what I have provided? Commented Mar 14, 2011 at 21:51
  • Valid XML should have only one root node. Wrap your divs with <html><body>..</body></html> and everything will be ok. Commented Mar 14, 2011 at 21:52
  • because there may be problem. Your XPath testing tool allows not valid XML documents :) While the one I'm referencing in my comment produces XML Error: System.Xml.XmlException: There are multiple root elements. Line 4, position 2. at System.Xml.XmlTextReaderImpl.Throw(Exception e) when the same document is supplied. Commented Mar 14, 2011 at 21:54
  • Check my answer for the well known and proper way to express this in XPath 1.0 Commented Mar 14, 2011 at 22:48

3 Answers 3

2

The classic XPath 1.0 answer for this existencial test on sequence is:

/html/body//div[
   contains(
      concat(' ',normalize-space(@class),' '),
      ' product-name '
   )
]
Sign up to request clarification or add additional context in comments.

Comments

1

You can use contains():

/html/body//div[contains(@class, 'product-name')]

Update:

As @Alejandro points out in his comment, this would also match any class that contains product-name. See his answer for a XPath 1.0 solution.

If you use XPath 2.0, you could also do this:

/html/body//div[exists(index-of(tokenize(@class, "\s+"), "product-name"))]

7 Comments

Doesn't pick up the second div, also checked here emdin-here.ru/r/xpath_checker
@OrW: This solution is correct (as per your question). If it does not work for you, your question does not represent your problem.
@OrW: It works for me. Are you passing the right document? If you are using the exact XPath above, the document must include html and body nodes. Or remove /html/body from the path and try again.
@OrW: You provided a not valid XML document. A XML document has always only one root node. Put both divs and a <root> element or in <html><body>....
@OrW: Your're welcome :) To be honest, I did the same mistake ;) :D
|
0

/html/body//div[contains(@class,'product-name')]

Attributes are also nodes, they are called attribute nodes.

2 Comments

For some reason, that still does not pick up the product-name gold
please verify that your code is correct. The //div part is correct and meets your requirements. Verify that not matching div is descendant of the /html/body. You can verify this XPath f.i. at xmlme.com/XpathTool.aspx

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.