mirror of
https://github.com/MontFerret/ferret.git
synced 2024-12-12 11:15:14 +02:00
Bugfix/#421 xpath (#435)
* Fixed attr retrieval using XPATH in CDP * Updated single node value in CDP * Added e2e test * Fixed attr retrieval with XPATH for HTTP driver * Update Makefile * Update attr.fql
This commit is contained in:
parent
2dd5457f8c
commit
145a16f97d
6
e2e/tests/dynamic/doc/xpath/attr.fql
Normal file
6
e2e/tests/dynamic/doc/xpath/attr.fql
Normal file
@ -0,0 +1,6 @@
|
||||
LET url = @dynamic
|
||||
LET page = DOCUMENT(url, { driver: "cdp" })
|
||||
|
||||
LET actual = XPATH(page, "//meta/@charset")
|
||||
|
||||
RETURN EXPECT(["utf-8"], actual)
|
@ -1,5 +1,5 @@
|
||||
LET url = @dynamic
|
||||
LET page = DOCUMENT(url, true)
|
||||
LET page = DOCUMENT(url, { driver: "cdp" })
|
||||
|
||||
LET actual = XPATH(page, "count(//body)")
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
LET url = @dynamic + "?redirect=/forms"
|
||||
LET page = DOCUMENT(url, true)
|
||||
LET page = DOCUMENT(url, { driver: "cdp" })
|
||||
|
||||
LET actual = XPATH(page, "//div[contains(@class, 'form-group')]")
|
||||
|
||||
|
6
e2e/tests/static/doc/xpath/attr.fql
Normal file
6
e2e/tests/static/doc/xpath/attr.fql
Normal file
@ -0,0 +1,6 @@
|
||||
LET url = @static + '/simple.html'
|
||||
LET page = DOCUMENT(url)
|
||||
|
||||
LET actual = XPATH(page, "//meta/@charset")
|
||||
|
||||
RETURN EXPECT(["UTF-8"], actual)
|
@ -627,6 +627,19 @@ func (el *HTMLElement) XPath(ctx context.Context, expression values.String) (res
|
||||
continue
|
||||
}
|
||||
|
||||
// it's not a Node, it's an attr value
|
||||
if descr.Value.ObjectID == nil {
|
||||
var value interface{}
|
||||
|
||||
if err := json.Unmarshal(descr.Value.Value, &value); err != nil {
|
||||
return values.None, err
|
||||
}
|
||||
|
||||
result.Push(values.Parse(value))
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
repl, err := el.client.DOM.RequestNode(ctx, dom.NewRequestNodeArgs(*descr.Value.ObjectID))
|
||||
|
||||
if err != nil {
|
||||
@ -656,7 +669,13 @@ func (el *HTMLElement) XPath(ctx context.Context, expression values.String) (res
|
||||
return result, nil
|
||||
case "object":
|
||||
if out.ObjectID == nil {
|
||||
return values.None, nil
|
||||
var value interface{}
|
||||
|
||||
if err := json.Unmarshal(out.Value, &value); err != nil {
|
||||
return values.None, err
|
||||
}
|
||||
|
||||
return values.Parse(value), nil
|
||||
}
|
||||
|
||||
repl, err := el.client.DOM.RequestNode(ctx, dom.NewRequestNodeArgs(*out.ObjectID))
|
||||
|
@ -2,6 +2,9 @@ package templates
|
||||
|
||||
const xPathTemplate = `
|
||||
(element, expression) => {
|
||||
const unwrap = (item) => {
|
||||
return item.nodeType != 2 ? item : item.nodeValue;
|
||||
};
|
||||
const out = document.evaluate(
|
||||
expression,
|
||||
element,
|
||||
@ -17,7 +20,7 @@ const xPathTemplate = `
|
||||
let item;
|
||||
|
||||
while ((item = out.iterateNext())) {
|
||||
result.push(item);
|
||||
result.push(unwrap(item));
|
||||
}
|
||||
|
||||
break;
|
||||
@ -30,7 +33,7 @@ const xPathTemplate = `
|
||||
const item = out.snapshotItem(i);
|
||||
|
||||
if (item != null) {
|
||||
result.push(item);
|
||||
result.push(unwrap(item));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -49,7 +52,7 @@ const xPathTemplate = `
|
||||
}
|
||||
case XPathResult.ANY_UNORDERED_NODE_TYPE:
|
||||
case XPathResult.FIRST_ORDERED_NODE_TYPE: {
|
||||
result = out.singleNodeValue;
|
||||
result = unwrap(out.singleNodeValue);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
@ -15,20 +15,26 @@ import (
|
||||
)
|
||||
|
||||
func parseXPathNode(nav *htmlquery.NodeNavigator) (core.Value, error) {
|
||||
node := nav.Current()
|
||||
|
||||
if node == nil {
|
||||
return values.None, nil
|
||||
}
|
||||
|
||||
switch nav.NodeType() {
|
||||
case xpath.ElementNode:
|
||||
node := nav.Current()
|
||||
|
||||
if node == nil {
|
||||
return values.None, nil
|
||||
}
|
||||
|
||||
return NewHTMLElement(&goquery.Selection{Nodes: []*html.Node{node}})
|
||||
case xpath.RootNode:
|
||||
node := nav.Current()
|
||||
|
||||
if node == nil {
|
||||
return values.None, nil
|
||||
}
|
||||
|
||||
url := htmlquery.SelectAttr(node, "url")
|
||||
return NewHTMLDocument(goquery.NewDocumentFromNode(node), url, nil)
|
||||
default:
|
||||
return values.Parse(node.Data), nil
|
||||
return values.NewString(nav.Value()), nil
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user