### 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 World
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(`
Laptop999.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 World
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 tutorialsRSS Tutorial
https://www.w3schools.com/xml/xml_rss.asp
New RSS tutorial on W3SchoolsXML 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 := `
ABC`
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 := `
RequestReplyActivityOpClientReqActivity30080`
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(`
Alice90000Bob85000Carol75000`))
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(`
GoRust`))
// 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.0025.507.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.99Rust49.99Python19.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 LanguageAlan Donovan39.99Clean CodeRobert Martin29.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.00pending75.50shipped200.00cancelled50.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(`
Alice90000Bob85000Carol75000`))
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(`
DuneFoundationA 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
}
```
```