mirror of
				https://github.com/MontFerret/ferret.git
				synced 2025-10-30 23:37:40 +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:
		
							
								
								
									
										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 | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user