### Install xmlquery Package Source: https://github.com/antchfx/xmlquery/blob/master/README.md Use 'go get' to install the xmlquery package. ```bash $ go get github.com/antchfx/xmlquery ``` -------------------------------- ### Find Books by Price Condition Source: https://github.com/antchfx/xmlquery/blob/master/README.md Filter book elements based on a condition applied to their child elements, such as price. This example finds books with a price less than 5. ```go list := xmlquery.Find(doc, "//book[price<5]") ``` -------------------------------- ### Find Book by ID Source: https://github.com/antchfx/xmlquery/blob/master/README.md Select book elements that have a specific attribute value using XPath. This example finds books with id 'bk104'. ```go list := xmlquery.Find(doc, "//book[@id='bk104']") ``` -------------------------------- ### Find Specific Book Element Source: https://github.com/antchfx/xmlquery/blob/master/README.md Locate a specific book element using its index in the XPath query. For example, '//book[2]' finds the second book. ```go book := xmlquery.FindOne(doc, "//book[2]") ``` -------------------------------- ### InnerText() - Get text content of a node Source: https://context7.com/antchfx/xmlquery/llms.txt Retrieves the concatenated text content of a node and all its descendants, excluding tags and comments. Useful for extracting plain text from XML elements. ```APIDOC ## (*Node).InnerText() string ### Description Returns the concatenated text content of a node and all its descendants, excluding tags and comments. ### Example Usage ```go import ( "fmt" "strings" "github.com/antchfx/xmlquery" ) func main() { doc, _ := xmlquery.Parse(strings.NewReader(`
Hello <em>World</em> First paragraph.
`)) title := xmlquery.FindOne(doc, "//title") fmt.Println(title.InnerText()) // Output: Hello World body := xmlquery.FindOne(doc, "//body") fmt.Println(body.InnerText()) // Output: First paragraph. Raw & content } ``` ``` -------------------------------- ### Get Attribute Value by Name Source: https://context7.com/antchfx/xmlquery/llms.txt Retrieve the value of a named attribute from an XML node using SelectAttr. Returns an empty string if the attribute is not found. Supports namespace-prefixed names. ```go import ( "fmt" "strings" "github.com/antchfx/xmlquery" ) func main() { doc, _ := xmlquery.Parse(strings.NewReader(` Laptop 999.99 `)) product := xmlquery.FindOne(doc, "//product") fmt.Println(product.SelectAttr("id")) // Output: p1 fmt.Println(product.SelectAttr("category")) // Output: electronics fmt.Println(product.SelectAttr("missing")) // Output: (empty string) price := xmlquery.FindOne(doc, "//price") fmt.Println(price.SelectAttr("currency")) // Output: USD fmt.Println(price.InnerText()) // Output: 999.99 } ``` -------------------------------- ### Get Text Content of a Node using InnerText() Source: https://context7.com/antchfx/xmlquery/llms.txt Use `InnerText()` to retrieve the concatenated text content of a node and its descendants, excluding tags and comments. This is useful for extracting human-readable text from XML elements. ```go import ( "fmt" "strings" "github.com/antchfx/xmlquery" ) func main() { doc, _ := xmlquery.Parse(strings.NewReader(`
Hello <em>World</em> First paragraph.
`)) title := xmlquery.FindOne(doc, "//title") fmt.Println(title.InnerText()) // Output: Hello World body := xmlquery.FindOne(doc, "//body") fmt.Println(body.InnerText()) // Output: First paragraph. Raw & content } ``` -------------------------------- ### Parse XML and Query Data with xmlquery Source: https://github.com/antchfx/xmlquery/blob/master/README.md Demonstrates parsing an XML string and querying elements using XPath. Ensure necessary packages like 'strings' and 'fmt' are imported. ```go import ( "fmt" "strings" "github.com/antchfx/xmlquery) func main(){ s := ` W3Schools Home Page https://www.w3schools.com Free web building tutorials RSS Tutorial https://www.w3schools.com/xml/xml_rss.asp New RSS tutorial on W3Schools XML Tutorial https://www.w3schools.com/xml New XML tutorial on W3Schools ` doc, err := xmlquery.Parse(strings.NewReader(s)) if err != nil { panic(err) } channel := xmlquery.FindOne(doc, "//channel") if n := channel.SelectElement("title"); n != nil { fmt.Printf("title: %s\n", n.InnerText()) } if n := channel.SelectElement("link"); n != nil { fmt.Printf("link: %s\n", n.InnerText()) } for i, n := range xmlquery.Find(doc, "//item/title") { fmt.Printf("#%d %s\n", i, n.InnerText()) } } ``` -------------------------------- ### Create XML Document Programmatically Source: https://github.com/antchfx/xmlquery/blob/master/README.md Illustrates building an XML document structure using xmlquery.Node objects without relying on xml.Marshal. The OutputXML and OutputXMLWithOptions methods can be used to serialize the document. ```go doc := &xmlquery.Node{ Type: xmlquery.DeclarationNode, Data: "xml", Attr: []xml.Attr{ xml.Attr{Name: xml.Name{Local: "version"}, Value: "1.0"}, }, } root := &xmlquery.Node{ Data: "rss", Type: xmlquery.ElementNode, } doc.FirstChild = root channel := &xmlquery.Node{ Data: "channel", Type: xmlquery.ElementNode, } root.FirstChild = channel title := &xmlquery.Node{ Data: "title", Type: xmlquery.ElementNode, } title_text := &xmlquery.Node{ Data: "W3Schools Home Page", Type: xmlquery.TextNode, } title.FirstChild = title_text channel.FirstChild = title fmt.Println(doc.OutputXML(true)) fmt.Println(doc.OutputXMLWithOptions(WithOutputSelf())) ``` -------------------------------- ### Serialize Node to XML with OutputXMLWithOptions() Source: https://context7.com/antchfx/xmlquery/llms.txt Use `OutputXMLWithOptions()` to serialize a node with fine-grained control over output formatting, including self-inclusion, comment suppression, empty tag style, and indentation. This is useful for generating formatted XML output. ```go import ( "fmt" "strings" "github.com/antchfx/xmlquery" ) func main() { doc, _ := xmlquery.Parse(strings.NewReader(` value `)) root := xmlquery.FindOne(doc, "//root") out := root.OutputXMLWithOptions( xmlquery.WithOutputSelf(), xmlquery.WithoutComments(), xmlquery.WithEmptyTagSupport(), xmlquery.WithIndentation(" "), ) fmt.Println(out) // Output: // // value // // } ``` -------------------------------- ### Serialize Node to XML with OutputXML() Source: https://context7.com/antchfx/xmlquery/llms.txt Use `OutputXML()` to serialize a node back to an XML string. The `self` parameter determines whether the node itself is included in the output. ```go import ( "fmt" "strings" "github.com/antchfx/xmlquery" ) func main() { doc, _ := xmlquery.Parse(strings.NewReader(` value `)) item := xmlquery.FindOne(doc, "//item") // Children only (self=false) fmt.Println(item.OutputXML(false)) // Output: value // Include self (self=true) fmt.Println(item.OutputXML(true)) // Output: value } ``` -------------------------------- ### Query All Elements with XPath Source: https://github.com/antchfx/xmlquery/blob/master/README.md Use QueryAll to find all elements matching the specified XPath expression. Handle potential errors during the query. ```go list, err := xmlquery.QueryAll(doc, "a") if err != nil { panic(err) } ``` -------------------------------- ### Load XML from URL Source: https://context7.com/antchfx/xmlquery/llms.txt Fetches and parses an XML document from a given URL. It validates the Content-Type header before parsing. ```go import ( "fmt" "github.com/antchfx/xmlquery" ) func main() { doc, err := xmlquery.LoadURL("https://www.w3schools.com/xml/simple.xml") if err != nil { panic(fmt.Sprintf("failed to load XML: %v", err)) } // Iterate top-level children for child := doc.FirstChild; child != nil; child = child.NextSibling { fmt.Printf("Node: %s (type=%d)\n", child.Data, child.Type) } } ``` -------------------------------- ### Parse XML from URL Source: https://github.com/antchfx/xmlquery/blob/master/README.md Load and parse an XML document directly from a given URL. Ensure the URL is valid and accessible. ```go doc, err := xmlquery.LoadURL("http://www.example.com/sitemap.xml") ``` -------------------------------- ### Query XML with Pre-compiled XPath Expressions Source: https://context7.com/antchfx/xmlquery/llms.txt Use QuerySelector and QuerySelectorAll with pre-compiled xpath.Expr for efficiency in hot paths. Avoids re-parsing the XPath string on every call. ```go import ( "fmt" "strings" "github.com/antchfx/xpath" "github.com/antchfx/xmlquery" ) func main() { xml := ` A B C ` doc, _ := xmlquery.Parse(strings.NewReader(xml)) // Compile once, reuse many times expr, err := xpath.Compile("//item[@status='active']") if err != nil { panic(err) } // QuerySelectorAll: all matches nodes := xmlquery.QuerySelectorAll(doc, expr) for _, n := range nodes { fmt.Println(n.SelectElement("name").InnerText()) } // Output: A, C // QuerySelector: first match only first := xmlquery.QuerySelector(doc, expr) fmt.Println(first.SelectElement("name").InnerText()) // Output: A } ``` -------------------------------- ### Calculate Total Price of Books Source: https://github.com/antchfx/xmlquery/blob/master/README.md Re-demonstrates evaluating the sum of book prices using a compiled XPath expression. Ensure the 'xpath' package is imported. ```go expr, err := xpath.Compile("sum(//book/price)") price := expr.Evaluate(xmlquery.CreateXPathNavigator(doc)).(float64) ``` -------------------------------- ### Query XML with Custom Namespace Prefix Source: https://github.com/antchfx/xmlquery/blob/master/README.md Shows how to compile an XPath expression with a custom namespace map to query XML elements. Ensure the namespace URIs in the map match those in the XML document. ```go s := ` RequestReplyActivity OpClientReqActivity 300 80 ` nsMap := map[string]string{ "q": "http://xmlns.xyz.com/process/2003", "r": "http://www.w3.org/1999/XSL/Transform", "s": "http://www.w3.org/2001/XMLSchema", } expr, _ := xpath.CompileWithNS("//q:activity", nsMap) node := xmlquery.QuerySelector(doc, expr) ``` -------------------------------- ### Find All Nodes with Error Handling in Go xmlquery Source: https://context7.com/antchfx/xmlquery/llms.txt Use `QueryAll` for finding all matching nodes, returning an error for invalid XPath expressions instead of panicking. This is recommended for production code, especially with dynamic or user-supplied XPath. ```go import ( "fmt" "strings" "github.com/antchfx/xmlquery" ) func main() { doc, _ := xmlquery.Parse(strings.NewReader(` Alice90000 Bob85000 Carol75000 `)) nodes, err := xmlquery.QueryAll(doc, "//employee[@dept='eng']") if err != nil { fmt.Println("invalid XPath:", err) return } for _, n := range nodes { fmt.Println(n.SelectElement("name").InnerText()) } // Output: // Alice // Bob // Invalid XPath returns error, not panic _, err = xmlquery.QueryAll(doc, "//[invalid") fmt.Println(err != nil) // Output: true } ``` -------------------------------- ### Parse XML from String Source: https://github.com/antchfx/xmlquery/blob/master/README.md Parse an XML document provided as a string. The string must contain valid XML content. ```go s := `` doc, err := xmlquery.Parse(strings.NewReader(s)) ``` -------------------------------- ### Find First Matching Node with Go xmlquery Source: https://context7.com/antchfx/xmlquery/llms.txt Use `FindOne` to retrieve the first node that matches an XPath expression. It returns `nil` if no node is found and panics on invalid XPath. ```go import ( "fmt" "strings" "github.com/antchfx/xmlquery" ) func main() { doc, _ := xmlquery.Parse(strings.NewReader(` Go Rust `)) // First book first := xmlquery.FindOne(doc, "//book[1]") fmt.Println(first.SelectAttr("id")) // Output: bk101 // Last book last := xmlquery.FindOne(doc, "//book[last()]") fmt.Println(last.SelectAttr("id")) // Output: bk102 // Book with specific id attribute book := xmlquery.FindOne(doc, "//book[@id='bk102']") if book != nil { fmt.Println(book.SelectElement("title").InnerText()) // Output: Rust } // Non-existent node returns nil missing := xmlquery.FindOne(doc, "//magazine") fmt.Println(missing == nil) // Output: true } ``` -------------------------------- ### Build and Mutate XML Node Tree Source: https://context7.com/antchfx/xmlquery/llms.txt Construct an XML document from scratch or modify an existing one by adding, removing, or querying nodes and their attributes. This is useful for generating XML output programmatically. ```go import ( "fmt" "encoding/xml" "github.com/antchfx/xmlquery" ) func main() { // Build a document from scratch doc := &xmlquery.Node{ Type: xmlquery.DeclarationNode, Data: "xml", Attr: []xmlquery.Attr{ {Name: xml.Name{Local: "version"}, Value: "1.0"}, {Name: xml.Name{Local: "encoding"}, Value: "UTF-8"}, }, } root := &xmlquery.Node{Type: xmlquery.ElementNode, Data: "catalog"} xmlquery.AddChild(doc, root) for i, title := range []string{"Go", "Rust", "Python"} { book := &xmlquery.Node{Type: xmlquery.ElementNode, Data: "book"} xmlquery.AddAttr(book, "id", fmt.Sprintf("bk%d", i+1)) titleNode := &xmlquery.Node{Type: xmlquery.ElementNode, Data: "title"} text := &xmlquery.Node{Type: xmlquery.TextNode, Data: title} xmlquery.AddChild(titleNode, text) xmlquery.AddChild(book, titleNode) xmlquery.AddChild(root, book) } fmt.Println(doc.OutputXMLWithOptions(xmlquery.WithOutputSelf(), xmlquery.WithIndentation(" "))) // Output: // // // Go // Rust // Python // // Remove a node second := xmlquery.FindOne(doc, "//book[@id='bk2']") xmlquery.RemoveFromTree(second) remaining := xmlquery.Find(doc, "//book") fmt.Println(len(remaining)) // Output: 2 // GetRoot from any node leaf := xmlquery.FindOne(doc, "//title") fmt.Println(xmlquery.GetRoot(leaf) == doc) // Output: true } ``` -------------------------------- ### XPath Namespace Queries and Aggregation Source: https://context7.com/antchfx/xmlquery/llms.txt Evaluate XPath expressions with namespaces using CompileWithNS and perform aggregations like sum and count using Evaluate with a custom XPath navigator. ```go import ( "fmt" "strings" "github.com/antchfx/xpath" "github.com/antchfx/xmlquery" ) func main() { // Namespace query nsXML := ` ` doc, _ := xmlquery.Parse(strings.NewReader(nsXML)) nsMap := map[string]string{ "p": "http://example.com/ns", } expr, _ := xpath.CompileWithNS("//p:item", nsMap) nodes := xmlquery.QuerySelectorAll(doc, expr) fmt.Println(len(nodes)) // Output: 3 // XPath aggregation: sum all prices plainXML := ` 10.00 25.50 7.99 ` doc2, _ := xmlquery.Parse(strings.NewReader(plainXML)) sumExpr, _ := xpath.Compile("sum(//book/price)") total := sumExpr.Evaluate(xmlquery.CreateXPathNavigator(doc2)).(float64) fmt.Printf("Total: %.2f\n", total) // Output: Total: 43.49 countExpr, _ := xpath.Compile("count(//book)") count := countExpr.Evaluate(xmlquery.CreateXPathNavigator(doc2)).(float64) fmt.Printf("Count: %.0f\n", count) // Output: Count: 3 } ``` -------------------------------- ### Load XML from a URL Source: https://context7.com/antchfx/xmlquery/llms.txt Fetches an XML document over HTTP/HTTPS and parses it. Validates the Content-Type header against known XML MIME types before parsing. ```APIDOC ## LoadURL(url string) (*Node, error) ### Description Fetches an XML document over HTTP/HTTPS and parses it. Validates the `Content-Type` header against known XML MIME types before parsing. ### Method ```go LoadURL(url string) (*Node, error) ``` ### Endpoint (Implicitly uses HTTP/HTTPS) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```go import ( "fmt" "github.com/antchfx/xmlquery" ) func main() { doc, err := xmlquery.LoadURL("https://www.w3schools.com/xml/simple.xml") if err != nil { panic(fmt.Sprintf("failed to load XML: %v", err)) } // Iterate top-level children for child := doc.FirstChild; child != nil; child = child.NextSibling { fmt.Printf("Node: %s (type=%d)\n", child.Data, child.Type) } } ``` ### Response #### Success Response (200) - **Node** (*Node) - The root node of the parsed XML document. - **error** (error) - An error if fetching or parsing fails. #### Response Example ```json { "example": "// Response structure depends on the fetched XML" } ``` ``` -------------------------------- ### Find All Matching Nodes with Go xmlquery Source: https://context7.com/antchfx/xmlquery/llms.txt Use `Find` to search for all nodes matching an XPath expression. This function panics if the XPath is invalid, so it's best used with known-good, constant expressions. ```go import ( "fmt" "strings" "github.com/antchfx/xmlquery" ) func main() { doc, _ := xmlquery.Parse(strings.NewReader(` Go39.99 Rust49.99 Python19.99 `)) // Find all books books := xmlquery.Find(doc, "//book") fmt.Println(len(books)) // Output: 3 // Find books with price < 40 cheap := xmlquery.Find(doc, "//book[price<40]") for _, b := range cheap { fmt.Println(b.SelectAttr("id"), b.SelectElement("title").InnerText()) } // Output: // bk101 Go // bk103 Python // Find all title text values for _, t := range xmlquery.Find(doc, "//book/title") { fmt.Println(t.InnerText()) } // Output: Go, Rust, Python } ``` -------------------------------- ### Parse XML from io.Reader Source: https://github.com/antchfx/xmlquery/blob/master/README.md Parse XML content from any io.Reader, such as a file. Ensure the file is opened correctly and error handling is in place. ```go f, err := os.Open("../books.xml") doc, err := xmlquery.Parse(f) ``` -------------------------------- ### Parse XML with Custom Options Source: https://context7.com/antchfx/xmlquery/llms.txt Parses XML with fine-grained control over charset handling, entity maps, strict mode, and line number tracking. Use ParserOptions.Decoder to configure the underlying xml.Decoder. ```go import ( "fmt" "strings" "io" "github.com/antchfx/xmlquery" "golang.org/x/text/encoding/unicode" "golang.org/x/text/transform" ) func main() { // Example 1: custom charset reader (e.g., for UTF-16 files) xmlStr := `hello` options := xmlquery.ParserOptions{ Decoder: &xmlquery.DecoderOptions{ CharsetReader: func(charset string, input io.Reader) (io.Reader, error) { // passthrough for demo; swap in a real charset decoder as needed return input, nil }, Strict: false, // tolerate malformed XML }, WithLineNumbers: true, } doc, err := xmlquery.ParseWithOptions(strings.NewReader(xmlStr), options) if err != nil { panic(err) } item := xmlquery.FindOne(doc, "//item") fmt.Println(item.InnerText()) // Output: hello fmt.Println(item.GetLineNumber()) // Output: 1 // Example 2: UTF-16 LE file // f, _ := os.Open("data.xml") // UTF-16 encoded file // utf16ToUtf8 := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewDecoder() // utf8Reader := transform.NewReader(f, utf16ToUtf8) // doc2, err := xmlquery.ParseWithOptions(utf8Reader, xmlquery.ParserOptions{}) _ = unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM) _ = transform.NewReader } ``` -------------------------------- ### Count Book Elements Source: https://github.com/antchfx/xmlquery/blob/master/README.md Employ XPath's 'count()' function to determine the number of elements matching a specific path. Compile the XPath expression before evaluation. ```go expr, err := xpath.Compile("count(//book)") count := expr.Evaluate(xmlquery.CreateXPathNavigator(doc)).(float64) ``` -------------------------------- ### OutputXML() / OutputXMLWithOptions - Serialize node back to XML Source: https://context7.com/antchfx/xmlquery/llms.txt Serializes a node back to an XML string. Options allow control over self-inclusion, empty tag style, comment suppression, whitespace preservation, and indentation. ```APIDOC ## (*Node).OutputXML(self bool) string / OutputXMLWithOptions ### Description Serializes a node (and optionally itself) back to an XML string. Options control self-inclusion, empty tag style, comment suppression, whitespace preservation, and indentation. ### Method Signatures - `OutputXML(self bool) string`: Serializes the node. If `self` is true, includes the node itself. - `OutputXMLWithOptions(options ...OutputOption) string`: Serializes the node with specified options. ### Example Usage ```go import ( "fmt" "strings" "github.com/antchfx/xmlquery" ) func main() { doc, _ := xmlquery.Parse(strings.NewReader(` value `)) item := xmlquery.FindOne(doc, "//item") // Children only (self=false) fmt.Println(item.OutputXML(false)) // Output: value // Include self (self=true) fmt.Println(item.OutputXML(true)) // Output: value // With options: skip comments, use empty tag support, indent output root := xmlquery.FindOne(doc, "//root") out := root.OutputXMLWithOptions( xmlquery.WithOutputSelf(), xmlquery.WithoutComments(), xmlquery.WithEmptyTagSupport(), xmlquery.WithIndentation(" "), ) fmt.Println(out) // Output: // // value // // } ``` ``` -------------------------------- ### Evaluate Sum of Book Prices Source: https://github.com/antchfx/xmlquery/blob/master/README.md Use XPath's 'sum()' function to calculate the total of numeric values from selected elements. Requires compiling the XPath expression first. ```go expr, err := xpath.Compile("sum(//book/price)") price := expr.Evaluate(xmlquery.CreateXPathNavigator(doc)).(float64) fmt.Printf("total price: %f\n", price) ``` -------------------------------- ### Find First Node with Error Handling in Go xmlquery Source: https://context7.com/antchfx/xmlquery/llms.txt Use `Query` to find the first matching node, returning an error for invalid XPath expressions. This is a safe alternative to `FindOne` for dynamic XPath queries. ```go import ( "fmt" "strings" "github.com/antchfx/xmlquery" ) func getNodeSafely(doc *xmlquery.Node, expr string) { node, err := xmlquery.Query(doc, expr) if err != nil { fmt.Printf("XPath error: %v\n", err) return } if node == nil { fmt.Println("not found") return } fmt.Println(node.InnerText()) } func main() { doc, _ := xmlquery.Parse(strings.NewReader(` localhost5432`)) getNodeSafely(doc, "//database/host") // Output: localhost getNodeSafely(doc, "//database/port") // Output: 5432 getNodeSafely(doc, "//database/pass") // Output: not found } ``` -------------------------------- ### Parse UTF-16 XML with Custom Decoder Source: https://github.com/antchfx/xmlquery/blob/master/README.md Demonstrates parsing a UTF-16 encoded XML file by setting a custom CharsetReader in ParserOptions. Ensure the input file is correctly encoded. ```go f, _ := os.Open(`UTF-16.XML`) // Convert UTF-16 XML to UTF-8 utf16ToUtf8Transformer := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewDecoder() utf8Reader := transform.NewReader(f, utf16ToUtf8Transformer) // Sets `CharsetReader` options := xmlquery.ParserOptions{ Decoder: &xmlquery.DecoderOptions{ CharsetReader: func(charset string, input io.Reader) (io.Reader, error) { return input, nil }, }, } doc, err := xmlquery.ParseWithOptions(utf8Reader, options) ``` -------------------------------- ### Parse XML from io.Reader Source: https://context7.com/antchfx/xmlquery/llms.txt Parses an entire XML document from an io.Reader. Returns an error if the XML is malformed or lacks a root element. ```go import ( "fmt" "strings" "github.com/antchfx/xmlquery" ) func main() { s := ` The Go Programming Language Alan Donovan 39.99 Clean Code Robert Martin 29.99 ` doc, err := xmlquery.Parse(strings.NewReader(s)) if err != nil { panic(err) } fmt.Println(doc.FirstChild.Data) // Output: xml (declaration node) fmt.Println(doc.LastChild.Data) // Output: bookstore } ``` -------------------------------- ### Stream Parse XML (Simple) Source: https://github.com/antchfx/xmlquery/blob/master/README.md Parse an XML file in a stream fashion for memory efficiency, especially with large files. This simple case processes elements matching the specified XPath. ```go f, _ := os.Open("../books.xml") p, err := xmlquery.CreateStreamParser(f, "/bookstore/book") for { n, err := p.Read() if err == io.EOF { break } if err != nil { panic(err) } fmt.Println(n) } ``` -------------------------------- ### QuerySelector / QuerySelectorAll with Pre-compiled XPath Source: https://context7.com/antchfx/xmlquery/llms.txt Use pre-compiled XPath expressions with QuerySelector and QuerySelectorAll to efficiently query XML documents, especially when the same expression is used multiple times. ```APIDOC ## QuerySelector / QuerySelectorAll ### Description Accept a pre-compiled `*xpath.Expr` object, avoiding re-parsing the XPath string on every call. Ideal for hot paths where the same expression is used repeatedly. ### Method `xmlquery.QuerySelectorAll(doc *xmlquery.Node, expr *xpath.Expr) []*xmlquery.Node` `xmlquery.QuerySelector(doc *xmlquery.Node, expr *xpath.Expr) *xmlquery.Node` ### Parameters #### Query Parameters - **doc** (*xmlquery.Node) - The root node of the XML document. - **expr** (*xpath.Expr) - The pre-compiled XPath expression. ### Request Example ```go // Compile once, reuse many times expr, err := xpath.Compile("//item[@status='active']") if err != nil { panic(err) } // QuerySelectorAll: all matches nodes := xmlquery.QuerySelectorAll(doc, expr) for _, n := range nodes { fmt.Println(n.SelectElement("name").InnerText()) } // QuerySelector: first match only first := xmlquery.QuerySelector(doc, expr) fmt.Println(first.SelectElement("name").InnerText()) ``` ### Response #### Success Response - **QuerySelectorAll**: Returns a slice of matching `*xmlquery.Node`. - **QuerySelector**: Returns the first matching `*xmlquery.Node` or nil if no match is found. ``` -------------------------------- ### Find All Book Authors Source: https://github.com/antchfx/xmlquery/blob/master/README.md Retrieve all author elements within book elements using XPath. Alternatively, use a more direct XPath if the structure allows. ```go list := xmlquery.Find(doc, "//book//author") // or list := xmlquery.Find(doc, "//author") ``` -------------------------------- ### Configure XPath Selector Cache Source: https://context7.com/antchfx/xmlquery/llms.txt Control the package's LRU XPath expression cache. Disable caching entirely by setting `DisableSelectorCache` to true, or adjust the cache size using `SelectorCacheMaxEntries`. A value of 0 or less also disables caching. ```go import "github.com/antchfx/xmlquery" func init() { // Disable caching entirely (useful for testing or one-off queries) xmlquery.DisableSelectorCache = true // Or increase cache size for applications with many distinct XPath expressions xmlquery.DisableSelectorCache = false xmlquery.SelectorCacheMaxEntries = 200 // Setting to 0 or negative also disables caching // xmlquery.SelectorCacheMaxEntries = 0 } ``` -------------------------------- ### Memory-Efficient Streaming Parse with CreateStreamParser() Source: https://context7.com/antchfx/xmlquery/llms.txt Use `CreateStreamParser()` to process large XML files without loading the entire document into memory. It yields one matching element at a time via `Read()`. An optional second XPath filter can be provided for fine-grained filtering after element completion. ```go import ( "fmt" "io" "strings" "github.com/antchfx/xmlquery" ) func main() { // Large XML (in practice, open a file with os.Open) largeXML := ` shipped150.00 pending75.50 shipped200.00 cancelled50.00 ` // Simple streaming: get all nodes sp, err := xmlquery.CreateStreamParser(strings.NewReader(largeXML), "/orders/order") if err != nil { panic(err) } for { n, err := sp.Read() if err == io.EOF { break } if err != nil { panic(err) } fmt.Printf("Order %s: %s\n", n.SelectAttr("id"), n.SelectElement("status").InnerText()) } // Output: // Order 1: shipped // Order 2: pending // Order 3: shipped // Order 4: cancelled // Advanced streaming: filter to shipped orders only sp2, _ := xmlquery.CreateStreamParser( strings.NewReader(largeXML), "/orders/order", "/orders/order[status='shipped']", // filter applied after element is fully parsed ) for { n, err := sp2.Read() if err == io.EOF { break } if err != nil { panic(err) } fmt.Printf("Shipped: %s total=%s\n", n.SelectAttr("id"), n.SelectElement("total").InnerText()) } // Output: // Shipped: 1 total=150.00 // Shipped: 3 total=200.00 } ``` -------------------------------- ### QueryAll(top *Node, expr string) ([]*Node, error) Source: https://context7.com/antchfx/xmlquery/llms.txt Finds all nodes matching the XPath expression, returning an error if the expression is invalid. This is a safer alternative to `Find` for dynamic or user-supplied XPath expressions. ```APIDOC ## QueryAll(top *Node, expr string) ([]*Node, error) ### Description Like `Find` but returns an error instead of panicking when `expr` is invalid. Prefer this in production code where the XPath expression may be user-supplied or dynamically constructed. ### Parameters - **top** (*Node) - The root node of the tree to search. - **expr** (string) - The XPath expression to match. ### Returns - `[]*Node` - A slice of matching nodes. - `error` - An error if the XPath expression is invalid, otherwise `nil`. ### Example ```go import ( "fmt" "strings" "github.com/antchfx/xmlquery" ) func main() { doc, _ := xmlquery.Parse(strings.NewReader(` Alice90000 Bob85000 Carol75000 `)) nodes, err := xmlquery.QueryAll(doc, "//employee[@dept='eng']") if err != nil { fmt.Println("invalid XPath:", err) return } for _, n := range nodes { fmt.Println(n.SelectElement("name").InnerText()) } // Output: // Alice // Bob // Invalid XPath returns error, not panic _, err = xmlquery.QueryAll(doc, "//[invalid") fmt.Println(err != nil) // Output: true } ``` ``` -------------------------------- ### XPath Namespace Queries and Aggregation Source: https://context7.com/antchfx/xmlquery/llms.txt Evaluate XPath expressions against namespaced XML documents using a custom namespace prefix map and perform aggregation functions like sum and count. ```APIDOC ## XPath Namespace Queries and Aggregation ### Description Evaluate full XPath expressions — including aggregation functions — against namespaced XML documents using a custom namespace prefix map. ### Method `xpath.CompileWithNS(xpathQuery string, nsMap map[string]string) (*xpath.Expr, error)` `expr.Evaluate(nav *xpath.NodeNavigator) interface{}` ### Parameters #### CompileWithNS Parameters - **xpathQuery** (string) - The XPath query string. - **nsMap** (map[string]string) - A map of namespace prefixes to URIs. #### Evaluate Parameters - **nav** (*xpath.NodeNavigator) - The XPath navigator for the XML document. ### Request Example ```go // Namespace query nsMap := map[string]string{ "p": "http://example.com/ns", } expr, _ := xpath.CompileWithNS("//p:item", nsMap) nodes := xmlquery.QuerySelectorAll(doc, expr) fmt.Println(len(nodes)) // XPath aggregation: sum all prices sumExpr, _ := xpath.Compile("sum(//book/price)") total := sumExpr.Evaluate(xmlquery.CreateXPathNavigator(doc2)).(float64) fmt.Printf("Total: %.2f\n", total) countExpr, _ := xpath.Compile("count(//book)") count := countExpr.Evaluate(xmlquery.CreateXPathNavigator(doc2)).(float64) fmt.Printf("Count: %.0f\n", count) ``` ### Response #### Success Response - **CompileWithNS**: Returns a compiled `*xpath.Expr` and an error if compilation fails. - **Evaluate**: Returns the result of the XPath expression evaluation (e.g., `float64` for sum/count). ``` -------------------------------- ### Parse XML with custom options Source: https://context7.com/antchfx/xmlquery/llms.txt Parses XML with fine-grained control over charset handling, entity maps, strict mode, and line number tracking. Use ParserOptions.Decoder to configure the underlying xml.Decoder, and WithLineNumbers: true to record source positions on each node. ```APIDOC ## ParseWithOptions(r io.Reader, options ParserOptions) (*Node, error) ### Description Parses XML with fine-grained control over charset handling, entity maps, strict mode, and line number tracking. Use `ParserOptions.Decoder` to configure the underlying `xml.Decoder`, and `WithLineNumbers: true` to record source positions on each node. ### Method ```go ParseWithOptions(r io.Reader, options ParserOptions) (*Node, error) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```go import ( "fmt" "strings" "io" "github.com/antchfx/xmlquery" "golang.org/x/text/encoding/unicode" "golang.org/x/text/transform" ) func main() { // Example 1: custom charset reader (e.g., for UTF-16 files) xmlStr := `hello` options := xmlquery.ParserOptions{ Decoder: &xmlquery.DecoderOptions{ CharsetReader: func(charset string, input io.Reader) (io.Reader, error) { // passthrough for demo; swap in a real charset decoder as needed return input, nil }, Strict: false, // tolerate malformed XML }, WithLineNumbers: true, } doc, err := xmlquery.ParseWithOptions(strings.NewReader(xmlStr), options) if err != nil { panic(err) } item := xmlquery.FindOne(doc, "//item") fmt.Println(item.InnerText()) // Output: hello fmt.Println(item.GetLineNumber()) // Output: 1 // Example 2: UTF-16 LE file // f, _ := os.Open("data.xml") // UTF-16 encoded file // utf16ToUtf8 := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewDecoder() // utf8Reader := transform.NewReader(f, utf16ToUtf8) // doc2, err := xmlquery.ParseWithOptions(utf8Reader, xmlquery.ParserOptions{}) _ = unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM) _ = transform.NewReader } ``` ### Response #### Success Response (200) - **Node** (*Node) - The root node of the parsed XML document. - **error** (error) - An error if parsing fails. #### Response Example ```json { "example": "// Response structure depends on the input XML and options" } ``` ``` -------------------------------- ### Stream Parse XML (Advanced Filtering) Source: https://github.com/antchfx/xmlquery/blob/master/README.md Advanced stream parsing of XML with multiple XPath filters. This allows for more specific element selection during the stream processing. ```go f, _ := os.Open("../books.xml") p, err := xmlquery.CreateStreamParser(f, "/bookstore/book", "/bookstore/book[price>=10]") for { n, err := p.Read() if err == io.EOF { break } if err != nil { panic(err) } fmt.Println(n) } ``` -------------------------------- ### Find Direct Child Elements by Name Source: https://context7.com/antchfx/xmlquery/llms.txt Use SelectElement and SelectElements to find direct child elements by tag name. These methods are convenient wrappers for FindOne and Find, respectively. ```go import ( "fmt" "strings" "github.com/antchfx/xmlquery" ) func main() { doc, _ := xmlquery.Parse(strings.NewReader(`
Dune Foundation
A Brief History
`)) library := xmlquery.FindOne(doc, "//library") // Select single child firstSection := library.SelectElement("section") fmt.Println(firstSection.SelectAttr("name")) // Output: fiction // Select all children with name sections := library.SelectElements("section") for _, s := range sections { fmt.Println(s.SelectAttr("name")) } // Output: fiction, science } ``` -------------------------------- ### Query(top *Node, expr string) (*Node, error) Source: https://context7.com/antchfx/xmlquery/llms.txt Finds the first node matching the XPath expression, returning an error if the expression is invalid. This is a safe alternative to `FindOne` for dynamic XPath expressions. ```APIDOC ## Query(top *Node, expr string) (*Node, error) ### Description Returns the first matching node and an error. Safe alternative to `FindOne` for dynamic XPath expressions. ### Parameters - **top** (*Node) - The root node of the tree to search. - **expr** (string) - The XPath expression to match. ### Returns - `*Node` - The first matching node, or `nil` if no match is found. - `error` - An error if the XPath expression is invalid, otherwise `nil`. ### Example ```go import ( "fmt" "strings" "github.com/antchfx/xmlquery" ) func getNodeSafely(doc *xmlquery.Node, expr string) { node, err := xmlquery.Query(doc, expr) if err != nil { fmt.Printf("XPath error: %v\n", err) return } if node == nil { fmt.Println("not found") return } fmt.Println(node.InnerText()) } func main() { doc, _ := xmlquery.Parse(strings.NewReader(` localhost5432`)) getNodeSafely(doc, "//database/host") // Output: localhost getNodeSafely(doc, "//database/port") // Output: 5432 getNodeSafely(doc, "//database/pass") // Output: not found } ``` ```