| [](https://travis-ci.org/beevik/etree) |
| [](https://godoc.org/github.com/beevik/etree) |
| |
| etree |
| ===== |
| |
| The etree package is a lightweight, pure go package that expresses XML in |
| the form of an element tree. Its design was inspired by the Python |
| [ElementTree](http://docs.python.org/2/library/xml.etree.elementtree.html) |
| module. |
| |
| Some of the package's capabilities and features: |
| |
| * Represents XML documents as trees of elements for easy traversal. |
| * Imports, serializes, modifies or creates XML documents from scratch. |
| * Writes and reads XML to/from files, byte slices, strings and io interfaces. |
| * Performs simple or complex searches with lightweight XPath-like query APIs. |
| * Auto-indents XML using spaces or tabs for better readability. |
| * Implemented in pure go; depends only on standard go libraries. |
| * Built on top of the go [encoding/xml](http://golang.org/pkg/encoding/xml) |
| package. |
| |
| ### Creating an XML document |
| |
| The following example creates an XML document from scratch using the etree |
| package and outputs its indented contents to stdout. |
| ```go |
| doc := etree.NewDocument() |
| doc.CreateProcInst("xml", `version="1.0" encoding="UTF-8"`) |
| doc.CreateProcInst("xml-stylesheet", `type="text/xsl" href="style.xsl"`) |
| |
| people := doc.CreateElement("People") |
| people.CreateComment("These are all known people") |
| |
| jon := people.CreateElement("Person") |
| jon.CreateAttr("name", "Jon") |
| |
| sally := people.CreateElement("Person") |
| sally.CreateAttr("name", "Sally") |
| |
| doc.Indent(2) |
| doc.WriteTo(os.Stdout) |
| ``` |
| |
| Output: |
| ```xml |
| <?xml version="1.0" encoding="UTF-8"?> |
| <?xml-stylesheet type="text/xsl" href="style.xsl"?> |
| <People> |
| <!--These are all known people--> |
| <Person name="Jon"/> |
| <Person name="Sally"/> |
| </People> |
| ``` |
| |
| ### Reading an XML file |
| |
| Suppose you have a file on disk called `bookstore.xml` containing the |
| following data: |
| |
| ```xml |
| <bookstore xmlns:p="urn:schemas-books-com:prices"> |
| |
| <book category="COOKING"> |
| <title lang="en">Everyday Italian</title> |
| <author>Giada De Laurentiis</author> |
| <year>2005</year> |
| <p:price>30.00</p:price> |
| </book> |
| |
| <book category="CHILDREN"> |
| <title lang="en">Harry Potter</title> |
| <author>J K. Rowling</author> |
| <year>2005</year> |
| <p:price>29.99</p:price> |
| </book> |
| |
| <book category="WEB"> |
| <title lang="en">XQuery Kick Start</title> |
| <author>James McGovern</author> |
| <author>Per Bothner</author> |
| <author>Kurt Cagle</author> |
| <author>James Linn</author> |
| <author>Vaidyanathan Nagarajan</author> |
| <year>2003</year> |
| <p:price>49.99</p:price> |
| </book> |
| |
| <book category="WEB"> |
| <title lang="en">Learning XML</title> |
| <author>Erik T. Ray</author> |
| <year>2003</year> |
| <p:price>39.95</p:price> |
| </book> |
| |
| </bookstore> |
| ``` |
| |
| This code reads the file's contents into an etree document. |
| ```go |
| doc := etree.NewDocument() |
| if err := doc.ReadFromFile("bookstore.xml"); err != nil { |
| panic(err) |
| } |
| ``` |
| |
| You can also read XML from a string, a byte slice, or an `io.Reader`. |
| |
| ### Processing elements and attributes |
| |
| This example illustrates several ways to access elements and attributes using |
| etree selection queries. |
| ```go |
| root := doc.SelectElement("bookstore") |
| fmt.Println("ROOT element:", root.Tag) |
| |
| for _, book := range root.SelectElements("book") { |
| fmt.Println("CHILD element:", book.Tag) |
| if title := book.SelectElement("title"); title != nil { |
| lang := title.SelectAttrValue("lang", "unknown") |
| fmt.Printf(" TITLE: %s (%s)\n", title.Text(), lang) |
| } |
| for _, attr := range book.Attr { |
| fmt.Printf(" ATTR: %s=%s\n", attr.Key, attr.Value) |
| } |
| } |
| ``` |
| Output: |
| ``` |
| ROOT element: bookstore |
| CHILD element: book |
| TITLE: Everyday Italian (en) |
| ATTR: category=COOKING |
| CHILD element: book |
| TITLE: Harry Potter (en) |
| ATTR: category=CHILDREN |
| CHILD element: book |
| TITLE: XQuery Kick Start (en) |
| ATTR: category=WEB |
| CHILD element: book |
| TITLE: Learning XML (en) |
| ATTR: category=WEB |
| ``` |
| |
| ### Path queries |
| |
| This example uses etree's path functions to select all book titles that fall |
| into the category of 'WEB'. The double-slash prefix in the path causes the |
| search for book elements to occur recursively; book elements may appear at any |
| level of the XML hierarchy. |
| ```go |
| for _, t := range doc.FindElements("//book[@category='WEB']/title") { |
| fmt.Println("Title:", t.Text()) |
| } |
| ``` |
| |
| Output: |
| ``` |
| Title: XQuery Kick Start |
| Title: Learning XML |
| ``` |
| |
| This example finds the first book element under the root bookstore element and |
| outputs the tag and text of each of its child elements. |
| ```go |
| for _, e := range doc.FindElements("./bookstore/book[1]/*") { |
| fmt.Printf("%s: %s\n", e.Tag, e.Text()) |
| } |
| ``` |
| |
| Output: |
| ``` |
| title: Everyday Italian |
| author: Giada De Laurentiis |
| year: 2005 |
| price: 30.00 |
| ``` |
| |
| This example finds all books with a price of 49.99 and outputs their titles. |
| ```go |
| path := etree.MustCompilePath("./bookstore/book[p:price='49.99']/title") |
| for _, e := range doc.FindElementsPath(path) { |
| fmt.Println(e.Text()) |
| } |
| ``` |
| |
| Output: |
| ``` |
| XQuery Kick Start |
| ``` |
| |
| Note that this example uses the FindElementsPath function, which takes as an |
| argument a pre-compiled path object. Use precompiled paths when you plan to |
| search with the same path more than once. |
| |
| ### Other features |
| |
| These are just a few examples of the things the etree package can do. See the |
| [documentation](http://godoc.org/github.com/beevik/etree) for a complete |
| description of its capabilities. |
| |
| ### Contributing |
| |
| This project accepts contributions. Just fork the repo and submit a pull |
| request! |