How I write an xpath instruction
First you need a basic knowledge of Xpath and Htlm. Read, at least once, documentation. I have found :
-for Xpath
https://developer.mozilla.org/En/XPath
http://www.w3.org/TR/xpath
http://www.w3schools.com/xpath/
-for Htlm
https://developer.mozilla.org/en/HTML/Element
https://developer.mozilla.org/en/HTML_E ... _Reference
http://htmlhelp.com/reference/html40/alist.html
http://htmlhelp.com/reference/html40/olist.html
http://www.w3.org/TR/html4/index/attributes.html
There are others that may be better for your tastes.
Now do not panic if you forget their big contents : If you find something in the source that looks like <input name="autologin" type="checkbox"> you may guess with confidence 99% that "input" (after the < it ends with >)is a tag, "name" and "type" (before =) are attributes and "autologin" and "checkbox" (between ") their content values even if you don't remember your lists !
When you define a character string to AHK or htlm, you have to use double-quote " around it, with the FF Xpath function you have the choice between double-quote " and simple-quote ' . You can test this on the iMacros demo page
http://www.iopus.com/imacros/demo/v6/pos/index.htm
by copying one of the following lines to your clipboard and use manually the ctrl+Q short-cut pasting somewhere the result ("Found") now in the clipboard :
nigelle;1;//input[@value='your E-mail here']
nigelle;1;//input[@value="your E-mail here"]
both will bring you in the Newsletter field in the upper right corner.
Now you have to write the AHK instruction calling the nxpath or rxpath functions adding " around it. It is : in the first case
rc := nxpath("nigelle;1;//input[@value='your E-mail here']")
in the second one
rc := nxpath("nigelle;1;//input[@value=""your E-mail here""]")
because you have to double each quote inside an AHK quoted string ! This is error prone and you cannot test easily your instruction by copying to your clipboard what is between the external quotes " of your instruction as I suggested in the text "Preparing to script". The source line you selected was
<input name="subscribe_email" type="text" class="txtbox" value="your E-mail here" />
So my advice is : use ' for strings inside xpath as in the first example.
The format of the parameter list of FF Xpath function is identifier;occurrence;XPath while for XPath most common are //tag[@attribute="value"] or //tag[contains(text(),"text content")] which is equivalent to my select() (with Ctrl+F) on the text part of the screen.
clarifications :
-the first field "identifier" is just a place holder and you can replace "nigelle" by any other string (but the same in shortcut and clipboard). We shall have in the future to decide if we keep "nigelle" (chosen by Dorando) which is good for my pride or replace it by something else e.g. AHK .
-the 2nd field "occurrence" is numeric [0-9] but can be greater than 9 e.g. 12.
-the 3rd field "XPath" : "tag" is the htlm tag without < and can be a td input or others ; "input" tag is used for the areas where you have to type entries e.g. user identifier, password, email, etc.. "a" (for anchor) tag is very common and has no special meaning.
-joker characters as * are not supported as in Imacros but you can use multiple checks like (all need to match): //input[@value="your E-mail here"][@name="subscribe_email"] .
-XPath 1.0 does not support case-insensitive matches.
-common attributes : "onclick" is frequently used when you click on an area that do some processing (e.g. Javascript function as in 'onclick="functionXx(...)' ), "href" introduce normally an URL with coding either relative to the domain or absolute but may also introduce Javascript function. With "input" tag you have very often a "name" attribute.
What syntax can I use to select ?
To define an attribute put @ before its name, its content value is between ' (if a default value is defined, it is shown in the @value attribute).
rc := nxpath("nigelle;1;//input[@name='username']") ; = means strictly equal, easy in many cases, very strict.
rc := nxpath("nigelle;1;//a[contains(@onclick,'return function_name')]") ; contains (note the s) is self explanatory, very easy but not very strict, generally sufficient.
rc := nxpath("nigelle;2;//a[starts-with(@onclick,'ClickFunc(')]") ; starts-with (note the s and -) is self explanatory, easy more strict.
rc := nxpath("nigelle;2;//a[ends-with(@onclick,'abcd)')]") ; ends-with (note the s and -) is self explanatory, easy more strict.
rc := nxpath("nigelle;1;//a[contains(text(),'some text')]") ;select "some text" in text part
I have found the examples given by
http://www.exampledepot.com/egs/org.w3c ... html?l=rel
"Finding Elements by Attributes in a DOM Document Using XPath"
(and others) very useful to understand what I do.
What element to choose ?
e.g. in the line used by AHKlogB.ahk script or the line prepared in one of the files defined in "Preparing to script"
<input class="post" name="username" size="25" maxlength="40" value="" type="text">
The principle is : something that is not commonly used in various places, that cause problem (e.g. need modifications) to the application if changed, is not used by the stylists to make the screen better looking.
With "input" tag the best candidate is often "name" attribute and its content : practically always the string 'name="its_content"' is unique in the source. This is due to the way your input data is transferred to (and used by) the application with method="post". As yo can see in the cited script other attributes as class, size, maxlength, value or type are used elsewhere and not a good choice. In other cases, "class" points to a small category and can be used.
Once you have chosen a candidate e.g. 'attribute="its_content"' you test your source see "Preparing to script" for the number of occurrences (hopefully 1) and choose an other if needed.
How to code ?
As usually it is easier to modify something already existing (see my Lxpath.txt file below). So you copy a model below your source line, correct it by pasting what is different in the source (e.g. attribute or its_content). I assume that you have now :
rc := nxpath("nigelle;1;//input[@name='username']")
you copy in your clipboard what is between the external " . It is :
nigelle;1;//input[@name='username']
go to the corresponding FF screen and use manually the ctrl+Q short-cut. Then paste the result now in the clipboard in the empty line below.
-If it is "Found" (and the FF cursor is in right field) that means success, you can go to the next action.
-If it is "NotFound" that means that the format of your instruction was right but that nothing has been selected. The error is probably in the occurrence value or some misspelling in attribute name or its content. Correct and try again !
-If it looks like
[Exception... "The expression is not a legal expression." code: "51" nsresult: "0x805b0033 (NS_ERROR_DOM_INVALID_EXPRESSION_ERR)" location: "chrome://browser/content/browser.xul Line: 8"]
that means that the format of your instruction was wrong. Check your ( " ; / [ @ ' ] ) and their pairing then correct and try again !
My Lxpath.txt file lists some xpath codings I have used : maintain a similar file (you may also add the corresponding source line).
rc := nxpath("nigelle;1;//input[@name='username']") ; go to the user field
rc := nxpath("nigelle;1;//a[contains(text(),'some text')]") ;select "some text" in text part
rc := nxpath("nigelle;1;//a[contains(text(),'Disconnect')]") ; click on "Disconnect" labelled button
rc := nxpath("nigelle;1;//input[@name='validate']") ; "validate" button
rc := nxpath("nigelle;1;//input[@class='login_valid']") ; OK button for login
If ! rctxp := rxpath("nigelle;1;//input[@class='special_box']") ; if the "special_box" exist, do some processing
rc := nxpath("nigelle;1;//a[contains(@href,'xxx.asp')]") ; click on a link
More elaborate examples
rc := nxpath("nigelle;1;//a[contains(@onclick,'return function_name')]") ; click on Javascript function_name by name only
rc := nxpath("nigelle;1;//a[contains(@href,'javascript:function(" . var . "')]") ; click on Javascript function by name and data previously extracted
rc := nxpath("nigelle;2;//a[contains(@onclick,'" . pp . "')]") ; click on Javascript function only by data previously extracted
Random, rand, 1, 6
rc := nxpath("nigelle;" . rand . ";//a[contains(@onclick,'BanClick')]") ; Randomly select an advertizing banner among 6 defined by function name in other cases something like ...//a[@class='banner']") may be used.