How to build XPath with [0-9] regex expression - xpath

Hi is there anyone can help me how to build the xpath for below 2 different XPath values?
//*[#id="EditorPanel"]/div[3]/div/table[1]/tbody/tr/td/table[1]
//*[#id="EditorPanel"]/div[4]/div/table[1]/tbody/tr/td/table[1]
Im thinking something like
//*[#id="EditorPanel"]/div[3-4]/div/table[1]/tbody/tr/td/table[1]

div[3] is just an abbreviation of div[position() = 3], so you can use
//*[#id="EditorPanel"]/div[position() = 3 or position() = 4]/div/table[1]/tbody/tr/td/table[1]

Related

How can I extract certain strings with Xpath

<span>1 Bedroom, 1 Bath</span>
Hi
I am new in Xpath. And my English is not very well, but I'll try. I need to extract with Xpath only '1 Bedroom' and '1 Bath'. How can I do this?
Thank you a lot
You can use substring-after() and substring-before():
substring-before(span, ',')
substring-after(span, ', ')

Traversing and search with xpath

My code:
"/root/pharagraph/sentence[" + y + "]/sequence/word"
that is same like
"/root/pharagraph[1]/sentence[" + y + "]/sequence/word"
Problem is that I want something like:
"/root/pharagraph[*]/sentence[" + y + "]/sequence/word"
So my Xpath search the sentence y in first pharagraph but I want to search sentence y in all pharagraphs.
No. Your first XPath expression is the same as your hypothetical XPath (the 3rd XPath). If you get only the first matched element using the 1st XPath, then the problem is in the code that execute the XPath, not in the XPath it self. For example, since I came from .NET, this might happen when one is using the wrong SelectSingleNode() method instead of the correct SelectNodes() to execute the XPath.

How to convert the int number into money format in X-path expression?

I want to convert the number (ie.1000) directly into into the money format like(ie.1,000).how should i do that?
In XSLT there is format-number(), but in pure XPath you'll have to do it the hard way. Perhaps you should do the formatting in the host language that you call XPath from?
You can use
<xsl:value-of select="format-number($wartosc, "###,###,###,###,##0.00")" />
You can use regex.
If $number is a string containing your integer number, then you can use:
replace(replace(
if (string-length($number) mod 3 eq 2) then concat("0", $number)
else if (string-length($number) mod 3 eq 1) then concat("00", $number)
else $number,
"([0-9]{3})", ",$1"),
"^[,0]+", "")

What is the best way to get 51, out of the following string

What is the best way to get '51', out of the following string in ruby :
"<https://api.example.com/users/lgs/api?page=2>; rel=\"next\", <https://api.example.com/users/lgs/api?page=51>; rel=\"last\""
Thanks in advance
Luca
If you know there're only two numbers in that string then this is enough:
str = '"<https://api.example.com/users/lgs/api?page=2>; rel=\"next\", <https://api.example.com/users/lgs/api?page=51>; rel=\"last\""'
p str.scan(/\d+/).last #=> "51"
If not then provide more detail to make the regex more precise. Also you can add to_i if you need the answer as a number.
You can use regexp in this way:
res = str.match /.page=(\d+)./
in this way you are "capturing all the digits between "(" and ")" (in the last token), and you result will be store in
res.captures.first
(or simply in $1 variable)

xpath expression for regex-like matching?

I want to search div id in an html doc with certain pattern.
I want to match this pattern in regex:
foo_([[:digit:]]{1.8})
using xpath. What is the xpath equivalent for the above pattern?
I'm stuck with //div[#id="foo_ and then what? If someone could continue a legal expression for it.
EDIT
Sorry, I think I have to elaborate more. Actually it's not foo_, it's post_message_
Btw, I use mechanize/nokogiri ( ruby )
Here's the snippet :
html_doc = Nokogiri::HTML(open(myfile))
message_div = html_doc.xpath('//div[substring(#id,13) = "post_message_" and substring-after(#id, "post_message_") => 0 and substring-after(#id, "post_message_") <= 99999999]')
Still failed. Error message:
Couldn't evaluate expression '//div[substring(#id,13) = "post_message_" and substring-after(#id, "post_message_") => 0 and substring-after(#id, "post_message_") <= 99999999]' (Nokogiri::XML::XPath::SyntaxError)
How about this (updated):
XPath 1.0:
"//div[substring-before(#id, '_') = 'foo'
and substring-after(#id, '_') >= 0
and substring-after(#id, '_') <= 99999999]"
Edit #2: The OP made a change to the question. The following, even more reduced XPath 1.0 expression works for me:
"//div[substring(#id, 1, 13) = 'post_message_'
and substring(#id, 14) >= 0
and substring(#id, 14) <= 99999999]"
XPath 2.0 has a convenient matches() function:
"//div[matches(#id, '^foo_\d{1,8}$')]"
Apart from the better portability, I would expect the numerical expression (XPath 1.0 style) to perform better than the regex test, though this would only become noticeable when processing large data sets.
Original version of the answer:
"//div[substring-before(#id, '_') = 'foo'
and number(substring-after(#id, '_')) = substring-after(#id, '_')
and number(substring-after(#id, '_')) >= 0
and number(substring-after(#id, '_')) <= 99999999]"
The use of the number() function is unnecessary, because the mathematical comparison operators coerce their arguments to numbers implicitly, any non-numbers will become NaN and the greater than/less than tests will fail.
I also removed the encoding of the angle brackets, since this is an XML requirement, not an XPath requirement.
As already pointed out, in XPath 2.0 it would be good to use its standard regex capabilities with a function like the matches() function.
One possible XPath 1.0 solution:
//div[starts-with(#id, 'post_message_')
and
string-length(#id) = 21
and
translate(substring-after(#id, 'post_message_'),
'0123456789',
''
)
=
''
]
Do note the following:
The use of the standard XPath function starts-with().
The use of the standard XPath function string-length().
The use of the standard XPath function substring-after().
The use of the standard XPath function translate().
Or use xpath function matches(string,pattern).
<xsl:if test="matches(name(.),'foo_')">
Unfortunately it's not regex, but it might be enough unless you have other foo_ tags you don't need, then I Guess you can add a few more "if" checks to cull them out.
Nikkou makes this very easy and readable:
doc.search('div').attr_matches('id', /post_message_\d{1,8}/)

Resources