{"id":13693665,"url":"https://github.com/antchfx/xmlquery","last_synced_at":"2025-05-14T15:04:54.408Z","repository":{"id":38360110,"uuid":"113114040","full_name":"antchfx/xmlquery","owner":"antchfx","description":"xmlquery is Golang XPath package for XML query.","archived":false,"fork":false,"pushed_at":"2025-03-15T04:11:10.000Z","size":257,"stargazers_count":462,"open_issues_count":15,"forks_count":92,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-10T03:50:13.669Z","etag":null,"topics":["go","golang","xml","xml-parser","xml-queries","xml-xpath","xpath"],"latest_commit_sha":null,"homepage":"https://github.com/antchfx/xpath","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/antchfx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-12-05T01:08:54.000Z","updated_at":"2025-04-07T03:15:10.000Z","dependencies_parsed_at":"2024-04-06T12:30:32.812Z","dependency_job_id":"9dc8ed08-4c5b-4303-bf2d-5f481fa50de3","html_url":"https://github.com/antchfx/xmlquery","commit_stats":null,"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antchfx%2Fxmlquery","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antchfx%2Fxmlquery/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antchfx%2Fxmlquery/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antchfx%2Fxmlquery/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/antchfx","download_url":"https://codeload.github.com/antchfx/xmlquery/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254168714,"owners_count":22026206,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","xml","xml-parser","xml-queries","xml-xpath","xpath"],"created_at":"2024-08-02T17:01:15.049Z","updated_at":"2025-05-14T15:04:54.377Z","avatar_url":"https://github.com/antchfx.png","language":"Go","readme":"# xmlquery\n\n[![Build Status](https://github.com/antchfx/xmlquery/actions/workflows/testing.yml/badge.svg)](https://github.com/antchfx/xmlquery/actions/workflows/testing.yml)\n[![GoDoc](https://godoc.org/github.com/antchfx/xmlquery?status.svg)](https://godoc.org/github.com/antchfx/xmlquery)\n[![Go Report Card](https://goreportcard.com/badge/github.com/antchfx/xmlquery)](https://goreportcard.com/report/github.com/antchfx/xmlquery)\n\n# Overview\n\n`xmlquery` is an XPath query package for XML documents, allowing you to extract\ndata or evaluate from XML documents with an XPath expression.\n\n`xmlquery` has a built-in query object caching feature that caches recently used\nXPATH query strings. Enabling caching can avoid recompile XPath expression for\neach query.\n\nYou can visit this page to learn about the supported XPath(1.0/2.0) syntax. https://github.com/antchfx/xpath\n\n[htmlquery](https://github.com/antchfx/htmlquery) - Package for the HTML document query.\n\n[xmlquery](https://github.com/antchfx/xmlquery) - Package for the XML document query.\n\n[jsonquery](https://github.com/antchfx/jsonquery) - Package for the JSON document query.\n\n# Installation\n\n```\n $ go get github.com/antchfx/xmlquery\n```\n\n# Quick Starts\n\n```go\nimport (\n\t\"github.com/antchfx/xmlquery\"\n)\n\nfunc main(){\n\ts := `\u003c?xml version=\"1.0\" encoding=\"UTF-8\" ?\u003e\n\u003crss version=\"2.0\"\u003e\n\u003cchannel\u003e\n  \u003ctitle\u003eW3Schools Home Page\u003c/title\u003e\n  \u003clink\u003ehttps://www.w3schools.com\u003c/link\u003e\n  \u003cdescription\u003eFree web building tutorials\u003c/description\u003e\n  \u003citem\u003e\n    \u003ctitle\u003eRSS Tutorial\u003c/title\u003e\n    \u003clink\u003ehttps://www.w3schools.com/xml/xml_rss.asp\u003c/link\u003e\n    \u003cdescription\u003eNew RSS tutorial on W3Schools\u003c/description\u003e\n  \u003c/item\u003e\n  \u003citem\u003e\n    \u003ctitle\u003eXML Tutorial\u003c/title\u003e\n    \u003clink\u003ehttps://www.w3schools.com/xml\u003c/link\u003e\n    \u003cdescription\u003eNew XML tutorial on W3Schools\u003c/description\u003e\n  \u003c/item\u003e\n\u003c/channel\u003e\n\u003c/rss\u003e`\n\n\tdoc, err := xmlquery.Parse(strings.NewReader(s))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tchannel := xmlquery.FindOne(doc, \"//channel\")\n\tif n := channel.SelectElement(\"title\"); n != nil {\n\t\tfmt.Printf(\"title: %s\\n\", n.InnerText())\n\t}\n\tif n := channel.SelectElement(\"link\"); n != nil {\n\t\tfmt.Printf(\"link: %s\\n\", n.InnerText())\n\t}\n\tfor i, n := range xmlquery.Find(doc, \"//item/title\") {\n\t\tfmt.Printf(\"#%d %s\\n\", i, n.InnerText())\n\t}\n}\n```\n\n# Getting Started\n\n### Find specified XPath query.\n\n```go\nlist, err := xmlquery.QueryAll(doc, \"a\")\nif err != nil {\n\tpanic(err)\n}\n```\n\n#### Parse an XML from URL.\n\n```go\ndoc, err := xmlquery.LoadURL(\"http://www.example.com/sitemap.xml\")\n```\n\n#### Parse an XML from string.\n\n```go\ns := `\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\u003crss version=\"2.0\"\u003e\u003c/rss\u003e`\ndoc, err := xmlquery.Parse(strings.NewReader(s))\n```\n\n#### Parse an XML from io.Reader.\n\n```go\nf, err := os.Open(\"../books.xml\")\ndoc, err := xmlquery.Parse(f)\n```\n\n#### Parse an XML in a stream fashion (simple case without elements filtering).\n\n```go\nf, _ := os.Open(\"../books.xml\")\np, err := xmlquery.CreateStreamParser(f, \"/bookstore/book\")\nfor {\n\tn, err := p.Read()\n\tif err == io.EOF {\n\t\tbreak\n\t}\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(n)\n}\n```\n\nNotes: `CreateStreamParser()` used for saving memory if your had a large XML file to parse.\n\n#### Parse an XML in a stream fashion (simple case advanced element filtering).\n\n```go\nf, _ := os.Open(\"../books.xml\")\np, err := xmlquery.CreateStreamParser(f, \"/bookstore/book\", \"/bookstore/book[price\u003e=10]\")\nfor {\n\tn, err := p.Read()\n\tif err == io.EOF {\n\t\tbreak\n\t}\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(n)\n}\n```\n\n#### Find authors of all books in the bookstore.\n\n```go\nlist := xmlquery.Find(doc, \"//book//author\")\n// or\nlist := xmlquery.Find(doc, \"//author\")\n```\n\n#### Find the second book.\n\n```go\nbook := xmlquery.FindOne(doc, \"//book[2]\")\n```\n\n#### Find the last book.\n\n```go\nbook := xmlquery.FindOne(doc, \"//book[last()]\")\n```\n\n#### Find all book elements and only get `id` attribute. \n\n```go\nlist := xmlquery.Find(doc,\"//book/@id\")\nfmt.Println(list[0].InnerText) // outout @id value\n```\n\n#### Find all books with id `bk104`.\n\n```go\nlist := xmlquery.Find(doc, \"//book[@id='bk104']\")\n```\n\n#### Find all books with price less than 5.\n\n```go\nlist := xmlquery.Find(doc, \"//book[price\u003c5]\")\n```\n\n#### Evaluate total price of all books.\n\n```go\nexpr, err := xpath.Compile(\"sum(//book/price)\")\nprice := expr.Evaluate(xmlquery.CreateXPathNavigator(doc)).(float64)\nfmt.Printf(\"total price: %f\\n\", price)\n```\n\n#### Count the number of books.\n\n```go\nexpr, err := xpath.Compile(\"count(//book)\")\ncount := expr.Evaluate(xmlquery.CreateXPathNavigator(doc)).(float64)\n```\n\n#### Calculate the total price of all book prices.\n\n```go\nexpr, err := xpath.Compile(\"sum(//book/price)\")\nprice := expr.Evaluate(xmlquery.CreateXPathNavigator(doc)).(float64)\n```\n\n# Advanced Features\n\n### Parse `UTF-16` XML file with `ParseWithOptions()`.\n\n```go\nf, _ := os.Open(`UTF-16.XML`)\n// Convert UTF-16 XML to UTF-8\nutf16ToUtf8Transformer := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewDecoder()\nutf8Reader := transform.NewReader(f, utf16ToUtf8Transformer)\n// Sets `CharsetReader`\noptions := xmlquery.ParserOptions{\n\tDecoder: \u0026xmlquery.DecoderOptions{\n\t\tCharsetReader: func(charset string, input io.Reader) (io.Reader, error) {\n\t\t\treturn input, nil\n\t\t},\n\t},\n}\ndoc, err := xmlquery.ParseWithOptions(utf8Reader, options)\n```\n\n### Query with custom namespace prefix.\n\n```go\ns := `\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cpd:ProcessDefinition xmlns:pd=\"http://xmlns.xyz.com/process/2003\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\u003e\n\u003cpd:activity name=\"Invoke Request-Response Service\"\u003e\n\u003cpd:type\u003eRequestReplyActivity\u003c/pd:type\u003e\n\u003cpd:resourceType\u003eOpClientReqActivity\u003c/pd:resourceType\u003e\n\u003cpd:x\u003e300\u003c/pd:x\u003e\n\u003cpd:y\u003e80\u003c/pd:y\u003e\n\u003c/pd:activity\u003e\n\u003c/pd:ProcessDefinition\u003e`\nnsMap := map[string]string{\n\t\"q\": \"http://xmlns.xyz.com/process/2003\",\n\t\"r\": \"http://www.w3.org/1999/XSL/Transform\",\n\t\"s\": \"http://www.w3.org/2001/XMLSchema\",\n}\nexpr, _ := xpath.CompileWithNS(\"//q:activity\", nsMap)\nnode := xmlquery.QuerySelector(doc, expr)\n```\n\n#### Create XML document without call `xml.Marshal`.\n\n```go\ndoc := \u0026xmlquery.Node{\n\tType: xmlquery.DeclarationNode,\n\tData: \"xml\",\n\tAttr: []xml.Attr{\n\t\txml.Attr{Name: xml.Name{Local: \"version\"}, Value: \"1.0\"},\n\t},\n}\nroot := \u0026xmlquery.Node{\n\tData: \"rss\",\n\tType: xmlquery.ElementNode,\n}\ndoc.FirstChild = root\nchannel := \u0026xmlquery.Node{\n\tData: \"channel\",\n\tType: xmlquery.ElementNode,\n}\nroot.FirstChild = channel\ntitle := \u0026xmlquery.Node{\n\tData: \"title\",\n\tType: xmlquery.ElementNode,\n}\ntitle_text := \u0026xmlquery.Node{\n\tData: \"W3Schools Home Page\",\n\tType: xmlquery.TextNode,\n}\ntitle.FirstChild = title_text\nchannel.FirstChild = title\n\nfmt.Println(doc.OutputXML(true))\nfmt.Println(doc.OutputXMLWithOptions(WithOutputSelf()))\n```\n\nOutput:\n\n```xml\n\u003c?xml version=\"1.0\"?\u003e\u003crss\u003e\u003cchannel\u003e\u003ctitle\u003eW3Schools Home Page\u003c/title\u003e\u003c/channel\u003e\u003c/rss\u003e\n```\n\n# FAQ\n\n#### `Find()` vs `QueryAll()`, which is better?\n\n`Find` and `QueryAll` both do the same thing: searches all of matched XML nodes.\n`Find` panics if provided with an invalid XPath query, while `QueryAll` returns\nan error.\n\n#### Can I save my query expression object for the next query?\n\nYes, you can. We provide `QuerySelector` and `QuerySelectorAll` methods; they\naccept your query expression object.\n\nCaching a query expression object avoids recompiling the XPath query\nexpression, improving query performance.\n\n# Questions\n\nPlease let me know if you have any questions\n","funding_links":[],"categories":["开源类库","Open source library","XML"],"sub_categories":["文本处理","Word Processing","Utility/Miscellaneous","Routers","路由器"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantchfx%2Fxmlquery","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fantchfx%2Fxmlquery","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantchfx%2Fxmlquery/lists"}