commit | 1d33bca5f3a723ae239ed3430b3c2aa7deaafe32 | [log] [tgz] |
---|---|---|
author | Brett Vickers <brett@beevik.com> | Sat Jan 26 10:02:10 2019 -0800 |
committer | Brett Vickers <brett@beevik.com> | Sat Jan 26 10:02:10 2019 -0800 |
tree | da7a106adaf0ec59f6cf40cd2dc87bbbad1b8ce0 | |
parent | b57c9972f47a101ec871cbca744479154042dba1 [diff] |
Add element Tail and SetTail methods. Tail returns the character data immediately following an element's end tag. SetTail modifies it. SetText now replaces runs of character data tokens (CDATA or text) with a single character data token. SetCData works similarly. The Token interface offers a new Index method, which returns the index of the token in its parent's child list. Added element RemoveChildAt and InsertChildAt methods. Both methods take an index as a parameter. Deprecated the element InsertChild method in favor of InsertChildAt.
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 module. Some of the package's features include:
The following example creates an XML document from scratch using the etree package and outputs its indented contents to stdout.
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 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>
Suppose you have a file on disk called bookstore.xml
containing the following data:
<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.
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
.
This example illustrates several ways to access elements and attributes using etree selection queries.
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
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.
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.
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.
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.
These are just a few examples of the things the etree package can do. See the documentation for a complete description of its capabilities.
This project accepts contributions. Just fork the repo and submit a pull request!