How to write an XPath query to match two attributes? - xpath

Following Question:
<div id="id-74385" class="guest clearfix" style="z-index: 999;">
Given above,
If I want a XPath expression with checks both id and class, can we do it w/ 'and' condition LIKE:
//div[#id='id-74385'] and div[#class='guest clearfix']
Is this correct way? My execution fails here... Please help!

//div[#id='..' and #class='...]
should do the trick. That's selecting the div operators that have both attributes of the required value.
It's worth using one of the online XPath testbeds to try stuff out.

or //div[#id='id-74385'][#class='guest clearfix']

Adding to Brian Agnew's answer.
You can also do //div[#id='..' or #class='...] and you can have parenthesized expressions inside //div[#id='..' and (#class='a' or #class='b')].

Sample XML:
<X>
<Y ATTRIB1=attrib1_value ATTRIB2=attrib2_value/>
</X>
string xPath="/" + X + "/" + Y +
"[#" + ATTRIB1 + "='" + attrib1_value + "']" +
"[#" + ATTRIB2 + "='" + attrib2_value + "']"
XPath Testbed:
http://www.whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm

Related

Perform an Xpath descendant search in jsoup

Here is my Xpath query i'm trying to convert to jsoup..
//div[#id='ad-display']/descendant-or-self::img[contains(#class, 'absmiddle')]/#src
I can't find any documentation that talks about descendants in jsoup. I know it talks about child elements, but apparently I'm not good enough to find the correlation between the two.
JSoup uses CSS selectors, selecting descendant in CSS is easy, just put your descendant element after ancestor separated by space.
Select by id is done with '#'. And select by class with '.'
Putting all together:
Document doc = Jsoup.parse("<div id='ad-display'><div><div>" +
"<img class='2'></img>" +
"<img class='absmiddle' src='src1'></img>" +
"<img class='dummy'></img>" +
"<img class='absmiddle' src='src2'></img>" +
"</div></div></div>");
Elements select = doc.select("div#ad-display img.absmiddle");
for (Element elem : select)
System.out.println(elem.attr("src"));
I added a mini-html as an example. Note imgs are inside a div inside a div inside the ancestor div (with id 'ad-display')
The output would be:
src1
src2
As expected.
I hope it will help.

How to use spring:eval expression inside $.each jQuery

After a ajax call the response received is a JSON String. I am able to list the data but was wondering if is it feasible to use spring:eval inside jQuery $.each? If someone has an example I would really appreciate. The line in question ends with "??"
Response received is JSON:
{"listOfData":[{"id":"XX","someValue":"James Bond"}]}
The rest of the code:
var obj = jQuery.parseJSON(JSON_String)
$.each(obj.listOfData, function (index, data) {
"<tr>" +
"<td style=\"padding: 3px;\">" +
(index + 1) +
"</td>" +
"<td style=\"padding: 3px;\">" +
<spring:eval expression="data.someValue" /> ??
"</td>" +
"</tr>" +
}
Depending on where this code is,
<td style=\"padding: 3px;\"><spring:eval expression=\"data.someValue\" /></td>
might work. If it doesn't, you could do the "eval" part server side and return ready-to-use datas from your JSON code.
If you are here then may be you are not on the right track. Try this solution. Works like a charm ... Solution 1 and similar solution Solution 2.

Using Xpath and HtmlAgilityPack to find all elements with innertext containing a specific word or words

I am trying to build a simple search-engine using HtmlAgilityPack and Xpath with C# (.NET 4).
I want to find every node containing a userdefined searchword, but I can't seem to get the XPath right.
For Example:
<HTML>
<BODY>
<H1>Mr T for president</H1>
<div>We believe the new president should be</div>
<div>the awsome Mr T</div>
<div>
<H2>Mr T replies:</H2>
<p>I pity the fool who doesn't vote</p>
<p>for Mr T</p>
</div>
</BODY>
</HTML>
If the specified searchword is "Mr T" I'd want the following nodes: <H1>, The second <div>, <H2> and the second <p>.
I have tried numerous variants of doc.DocumentNode.SelectNodes("//text()[contains(., "+ searchword +")]"); but I always seem to wind up with every single node in the entire DOM.
Any hints to get me in the right direction would be very appreciated.
Use:
//*[text()[contains(., 'Mr T')]]
This selects all elements in the XML document that have a text-node child which contains the string 'Mr T'.
This can also be written shorter as:
//text()[contains(., 'Mr T')]/..
This selects the parent(s) of any text node that contains the string 'Mr T'.
According to Xpath, if you want to find a specific keyword you need to follow the format ("keyword" is the word you like to search) :
//*[text()[contains(., 'keyword')]]
You have to follow the same format as above in C#, keyword is the string variable you call:
doc.DocumentNode.SelectNodes("//*[text()[contains(., '" + keyword + "')]]");
Use the following:
doc.DocumentNode.SelectNodes("//*[contains(text()[1], " + searchword + ")]")
This selects all elements (*) whose first text child (text()[1]) contains the searchword.
Case-insensitive solution:
var xpathForFindText =
"//*[text()[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), '" + lowerFocusKwd + "')]]";
var result=doc.DocumentNode.SelectNodes(xpathForFindText);
Note:
Be careful, because the lowerFocusKwd must not contain the following character, because the xpath will be in bad format:
'

Is this an optimal xpath query? [duplicate]

For example:
//person[#id='abc123']/#haircolor|/#weight"
PS. there are lots of "person" records
Try this:
//person[#id='abc123']/#*[name()='weight' or name()='haircolor']
If you're using an XPath 2.0 processor, you may also use a prettier option:
//person[#id='abc123']/(#haircolor|#weight)`
Are you wanting to search for person nodes based on the value of multiple attributes. If that's the question then you can just use ands e.g.
//person[#id='abc123' and #haircolor='blue' and #weight='...']
If you want to search on a single attribute, but return the values of the other attributes, I would do something like this:
<xsl:template match="person[#id='abc123']">
<xsl:value-of select="#haircolor"/>
<xsl:value-of select="#weight"/>
</xsl:template>
If you are trying to get the values of the specified attributes I would suggest introducing a variable for the requested person.
<xsl:variable name="person" select="//person[#id = 'abc123']" />
After that you can get any attribute from the requested person by using the specified variable.
<xsl:value-of select="$person/#haircolor" />
<xsl:value-of select="$person/#weight" />
Sample XML:
<X>
<Y ATTRIB1=attrib1_value ATTRIB2=attrib2_value/>
</X>
string xPath="/" + X + "/" + Y +
"[#" + ATTRIB1 + "='" + attrib1_value + "']" +
"[#" + ATTRIB2 + "='" + attrib2_value + "']"
XPath Testbed:
http://www.whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm

How to select two attributes from the same node with one expression in XPath?

For example:
//person[#id='abc123']/#haircolor|/#weight"
PS. there are lots of "person" records
Try this:
//person[#id='abc123']/#*[name()='weight' or name()='haircolor']
If you're using an XPath 2.0 processor, you may also use a prettier option:
//person[#id='abc123']/(#haircolor|#weight)`
Are you wanting to search for person nodes based on the value of multiple attributes. If that's the question then you can just use ands e.g.
//person[#id='abc123' and #haircolor='blue' and #weight='...']
If you want to search on a single attribute, but return the values of the other attributes, I would do something like this:
<xsl:template match="person[#id='abc123']">
<xsl:value-of select="#haircolor"/>
<xsl:value-of select="#weight"/>
</xsl:template>
If you are trying to get the values of the specified attributes I would suggest introducing a variable for the requested person.
<xsl:variable name="person" select="//person[#id = 'abc123']" />
After that you can get any attribute from the requested person by using the specified variable.
<xsl:value-of select="$person/#haircolor" />
<xsl:value-of select="$person/#weight" />
Sample XML:
<X>
<Y ATTRIB1=attrib1_value ATTRIB2=attrib2_value/>
</X>
string xPath="/" + X + "/" + Y +
"[#" + ATTRIB1 + "='" + attrib1_value + "']" +
"[#" + ATTRIB2 + "='" + attrib2_value + "']"
XPath Testbed:
http://www.whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm

Resources