问题
I'm using Casper.js to automate a regular upload. I've managed to upload the file and check if it's valid, but I'd like to parse the table which is returned if there's errors, but I get the error [error] [remote] findAll(): invalid selector provided "[object Object]":Error: SYNTAX_ERR: DOM Exception 12
. Here's the relevant part of my code:
casper.then(function() {
if (this.fetchText('.statusMessageContainer').match(/Sorry, the file did not pass validation. Please review the validation errors in the report below/)) {
this.echo("Upload failed!", "ERROR");
errors = this.evaluate(function() {
var errorRows = __utils__.findAll({
type: 'xpath',
path: '//table[@id="uploadTable"]/tr[position()>1]'
});
return Array.prototype.forEach.call(errorRows, function(e) {
return e;
});
});
this.echo(JSON.stringify(errors));
} else {
this.echo("Upload successful", "INFO");
}
});
Any ideas?
回答1:
While you probably have an XPath syntax error, you must know that you cannot return DOM elements from a closure passed to the evaluate()
method; you have to convert your NodeList
and HTMLelement
instances to some native Javascript types, eg. Arrays, Objects, strings, etc…
Also, there's a convenient getElementsByXPath() method in the ClientUtils module you can use from the __utils__
instance automatically injected in every page your load:
casper.then(function() {
if (this.fetchText('.statusMessageContainer').match(/Sorry, the file did not pass validation. Please review the validation errors in the report below/)) {
this.echo("Upload failed!", "ERROR");
var errors = this.evaluate(function() {
var errorRows = __utils__.getElementsByXPath('//table[@id="uploadTable"]/tr[position()>1]');
return Array.prototype.map.call(errorRows, function(e) {
return e.innerText; // let's get node text instead of HTMLelement!
});
});
this.echo(JSON.stringify(errors));
} else {
this.echo("Upload successful", "INFO");
}
});
You can also use the ClientUtils bookmarklet to test your selectors right within your browser console as well. For example here, click the bookmarklet and execute this in the js console:
__utils__.getElementsByXPath('//table[@id="uploadTable"]/tr[position()>1]')
Then you'll see if your selector is correct (it works by my side — I mean it is syntactically correct).
回答2:
Well from your error it appears there is something wrong with your selector.
It's setup correctly from what I can see, except for one thing: Try changing '//table[@id="uploadTable"]/tr[position()>1]'
to '//table[@id='uploadTable']/tr[position()>1]'
(change "" to '')
Other than that, your XPath looks syntactically correct, so I'm not sure why it would qualify as an invalid selector.
来源:https://stackoverflow.com/questions/10740907/getting-all-table-rows-and-returning-them-using-an-xpath-query-in-casperjs