README
¶
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 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 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.
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>
Reading an XML file
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
.
Processing elements and attributes
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
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.
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.
Other features
These are just a few examples of the things the etree package can do. See the documentation for a complete description of its capabilities.
Contributing
This project accepts contributions. Just fork the repo and submit a pull request!
Documentation
¶
Overview ¶
Package etree provides XML services through an Element Tree abstraction.
Index ¶
- Constants
- Variables
- type Attr
- type CharData
- type Comment
- type Directive
- type Document
- func (d *Document) Copy() *Document
- func (d *Document) Indent(spaces int)
- func (d *Document) IndentTabs()
- func (d *Document) ReadFrom(r io.Reader) (n int64, err error)
- func (d *Document) ReadFromBytes(b []byte) error
- func (d *Document) ReadFromFile(filename string) error
- func (d *Document) ReadFromString(s string) error
- func (d *Document) Root() *Element
- func (d *Document) SetRoot(e *Element)
- func (d *Document) WriteTo(w io.Writer) (n int64, err error)
- func (d *Document) WriteToBytes() (b []byte, err error)
- func (d *Document) WriteToFile(filename string) error
- func (d *Document) WriteToString() (s string, err error)
- type Element
- func (e *Element) AddChild(t Token)
- func (e *Element) ChildElements() []*Element
- func (e *Element) Copy() *Element
- func (e *Element) CreateAttr(key, value string) *Attr
- func (e *Element) CreateCData(data string) *CharData
- func (e *Element) CreateCharData(data string) *CharDatadeprecated
- func (e *Element) CreateComment(comment string) *Comment
- func (e *Element) CreateDirective(data string) *Directive
- func (e *Element) CreateElement(tag string) *Element
- func (e *Element) CreateProcInst(target, inst string) *ProcInst
- func (e *Element) CreateText(text string) *CharData
- func (e *Element) FindElement(path string) *Element
- func (e *Element) FindElementPath(path Path) *Element
- func (e *Element) FindElements(path string) []*Element
- func (e *Element) FindElementsPath(path Path) []*Element
- func (e *Element) FullTag() string
- func (e *Element) GetPath() string
- func (e *Element) GetRelativePath(source *Element) string
- func (e *Element) Index() int
- func (e *Element) InsertChild(ex Token, t Token)deprecated
- func (e *Element) InsertChildAt(index int, t Token)
- func (e *Element) NamespaceURI() string
- func (e *Element) Parent() *Element
- func (e *Element) RemoveAttr(key string) *Attr
- func (e *Element) RemoveChild(t Token) Token
- func (e *Element) RemoveChildAt(index int) Token
- func (e *Element) SelectAttr(key string) *Attr
- func (e *Element) SelectAttrValue(key, dflt string) string
- func (e *Element) SelectElement(tag string) *Element
- func (e *Element) SelectElements(tag string) []*Element
- func (e *Element) SetCData(text string)
- func (e *Element) SetTail(text string)
- func (e *Element) SetText(text string)
- func (e *Element) SortAttrs()
- func (e *Element) Tail() string
- func (e *Element) Text() string
- type ErrPath
- type Path
- type ProcInst
- type ReadSettings
- type Token
- type WriteSettings
Examples ¶
Constants ¶
const (
// NoIndent is used with Indent to disable all indenting.
NoIndent = -1
)
Variables ¶
var ErrXML = errors.New("etree: invalid XML format")
ErrXML is returned when XML parsing fails due to incorrect formatting.
Functions ¶
This section is empty.
Types ¶
type Attr ¶
type Attr struct {
Space, Key string // The attribute's namespace prefix and key
Value string // The attribute value string
// contains filtered or unexported fields
}
An Attr represents a key-value attribute of an XML element.
func (*Attr) FullKey ¶ added in v1.1.0
FullKey returns the attribute a's complete key, including namespace prefix if present.
func (*Attr) NamespaceURI ¶ added in v1.1.0
NamespaceURI returns the XML namespace URI associated with the attribute. If the element is part of the XML default namespace, NamespaceURI returns the empty string.
type CharData ¶
type CharData struct { Data string // contains filtered or unexported fields }
CharData can be used to represent character data or a CDATA section within an XML document.
func NewCharData
deprecated
func NewText ¶ added in v1.1.0
NewText creates a parentless CharData token containing character data.
func (*CharData) Index ¶ added in v1.1.0
Index returns the index of this CharData token within its parent element's list of child tokens. If this CharData token has no parent element, the index is -1.
func (*CharData) IsCData ¶ added in v1.1.0
IsCData returns true if the character data token is to be encoded as a CDATA section.
func (*CharData) IsWhitespace ¶ added in v1.1.0
IsWhitespace returns true if the character data token was created by one of the document Indent methods to contain only whitespace.
type Comment ¶
type Comment struct { Data string // contains filtered or unexported fields }
A Comment represents an XML comment.
func NewComment ¶
NewComment creates a parentless XML comment.
type Directive ¶
type Directive struct { Data string // contains filtered or unexported fields }
A Directive represents an XML directive.
func NewDirective ¶
NewDirective creates a parentless XML directive.
type Document ¶
type Document struct { Element ReadSettings ReadSettings WriteSettings WriteSettings }
A Document is a container holding a complete XML hierarchy. Its embedded element contains zero or more children, one of which is usually the root element. The embedded element may include other children such as processing instructions or BOM CharData tokens.
Example (Creating) ¶
Create an etree Document, add XML entities to it, and serialize it to 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 O'Reilly"/> <Person name="Sally"/> </People>
Example (Reading) ¶
Output:
func NewDocument ¶
func NewDocument() *Document
NewDocument creates an XML document without a root element.
func (*Document) Indent ¶
Indent modifies the document's element tree by inserting character data tokens containing newlines and indentation. The amount of indentation per depth level is given as spaces. Pass etree.NoIndent for spaces if you want no indentation at all.
func (*Document) IndentTabs ¶
func (d *Document) IndentTabs()
IndentTabs modifies the document's element tree by inserting CharData tokens containing newlines and tabs for indentation. One tab is used per indentation level.
func (*Document) ReadFrom ¶
ReadFrom reads XML from the reader r into the document d. It returns the number of bytes read and any error encountered.
func (*Document) ReadFromBytes ¶
ReadFromBytes reads XML from the byte slice b into the document d.
func (*Document) ReadFromFile ¶
ReadFromFile reads XML from the string s into the document d.
func (*Document) ReadFromString ¶
ReadFromString reads XML from the string s into the document d.
func (*Document) Root ¶
Root returns the root element of the document, or nil if there is no root element.
func (*Document) SetRoot ¶
SetRoot replaces the document's root element with e. If the document already has a root when this function is called, then the document's original root is unbound first. If the element e is bound to another document (or to another element within a document), then it is unbound first.
func (*Document) WriteTo ¶
WriteTo serializes an XML document into the writer w. It returns the number of bytes written and any error encountered.
func (*Document) WriteToBytes ¶
WriteToBytes serializes the XML document into a slice of bytes.
func (*Document) WriteToFile ¶
WriteToFile serializes an XML document into the file named filename.
func (*Document) WriteToString ¶
WriteToString serializes the XML document into a string.
type Element ¶
type Element struct {
Space, Tag string // namespace prefix and tag
Attr []Attr // key-value attribute pairs
Child []Token // child tokens (elements, comments, etc.)
// contains filtered or unexported fields
}
An Element represents an XML element, its attributes, and its child tokens.
func NewElement ¶
NewElement creates an unparented element with the specified tag. The tag may be prefixed by a namespace prefix and a colon.
func (*Element) AddChild ¶
AddChild adds the token t as the last child of element e. If token t was already the child of another element, it is first removed from its current parent element.
func (*Element) ChildElements ¶
ChildElements returns all elements that are children of element e.
func (*Element) Copy ¶
Copy creates a recursive, deep copy of the element and all its attributes and children. The returned element has no parent but can be parented to a another element using AddElement, or to a document using SetRoot.
func (*Element) CreateAttr ¶
CreateAttr creates an attribute and adds it to element e. The key may be prefixed by a namespace prefix and a colon. If an attribute with the key already exists, its value is replaced.
func (*Element) CreateCData ¶ added in v1.1.0
CreateCData creates a CharData token containing a CDATA section and adds it as a child of element e.
func (*Element) CreateCharData
deprecated
func (*Element) CreateComment ¶
CreateComment creates an XML comment and adds it as a child of element e.
func (*Element) CreateDirective ¶
CreateDirective creates an XML directive and adds it as the last child of element e.
func (*Element) CreateElement ¶
CreateElement creates an element with the specified tag and adds it as the last child element of the element e. The tag may be prefixed by a namespace prefix and a colon.
func (*Element) CreateProcInst ¶
CreateProcInst creates a processing instruction and adds it as a child of element e.
func (*Element) CreateText ¶ added in v1.1.0
CreateText creates a CharData token containing character data and adds it as a child of element e.
func (*Element) FindElement ¶
FindElement returns the first element matched by the XPath-like path string. Returns nil if no element is found using the path. Panics if an invalid path string is supplied.
func (*Element) FindElementPath ¶
FindElementPath returns the first element matched by the XPath-like path string. Returns nil if no element is found using the path.
func (*Element) FindElements ¶
FindElements returns a slice of elements matched by the XPath-like path string. Panics if an invalid path string is supplied.
func (*Element) FindElementsPath ¶
FindElementsPath returns a slice of elements matched by the Path object.
func (*Element) FullTag ¶ added in v1.1.0
FullTag returns the element e's complete tag, including namespace prefix if present.
func (*Element) GetRelativePath ¶ added in v1.0.1
GetRelativePath returns the path of the element relative to the source element. If the two elements are not part of the same element tree, then GetRelativePath returns the empty string.
func (*Element) Index ¶ added in v1.1.0
Index returns the index of this element within its parent element's list of child tokens. If this element has no parent element, the index is -1.
func (*Element) InsertChild
deprecated
InsertChild inserts the token t before e's existing child token ex. If ex is nil or ex is not a child of e, then t is added to the end of e's child token list. If token t was already the child of another element, it is first removed from its current parent element.
Deprecated: InsertChild is deprecated. Use InsertChildAt instead.
func (*Element) InsertChildAt ¶ added in v1.1.0
InsertChildAt inserts the token t into the element e's list of child tokens just before the requested index. If the index is greater than or equal to the length of the list of child tokens, the token t is added to the end of the list.
func (*Element) NamespaceURI ¶ added in v1.1.0
NamespaceURI returns the XML namespace URI associated with the element. If the element is part of the XML default namespace, NamespaceURI returns the empty string.
func (*Element) Parent ¶
Parent returns the element token's parent element, or nil if it has no parent.
func (*Element) RemoveAttr ¶
RemoveAttr removes and returns a copy of the first attribute of the element whose key matches the given key. The key may be prefixed by a namespace prefix and a colon. If a matching attribute does not exist, nil is returned.
func (*Element) RemoveChild ¶
RemoveChild attempts to remove the token t from element e's list of children. If the token t is a child of e, then it is returned. Otherwise, nil is returned.
func (*Element) RemoveChildAt ¶ added in v1.1.0
RemoveChildAt removes the index-th child token from the element e. The removed child token is returned. If the index is out of bounds, no child is removed and nil is returned.
func (*Element) SelectAttr ¶
SelectAttr finds an element attribute matching the requested key and returns it if found. Returns nil if no matching attribute is found. The key may be prefixed by a namespace prefix and a colon.
func (*Element) SelectAttrValue ¶
SelectAttrValue finds an element attribute matching the requested key and returns its value if found. The key may be prefixed by a namespace prefix and a colon. If the key is not found, the dflt value is returned instead.
func (*Element) SelectElement ¶
SelectElement returns the first child element with the given tag. The tag may be prefixed by a namespace prefix and a colon. Returns nil if no element with a matching tag was found.
func (*Element) SelectElements ¶
SelectElements returns a slice of all child elements with the given tag. The tag may be prefixed by a namespace prefix and a colon.
func (*Element) SetCData ¶ added in v1.1.0
SetCData replaces all character data immediately following an element's opening tag with a CDATA section.
func (*Element) SetTail ¶ added in v1.1.0
SetTail replaces all character data immediately following the element's end tag with the requested string.
func (*Element) SetText ¶
SetText replaces all character data immediately following an element's opening tag with the requested string.
func (*Element) SortAttrs ¶ added in v1.1.0
func (e *Element) SortAttrs()
SortAttrs sorts the element's attributes lexicographically by key.
type ErrPath ¶
type ErrPath string
ErrPath is returned by path functions when an invalid etree path is provided.
type Path ¶
type Path struct {
// contains filtered or unexported fields
}
A Path is a string that represents a search path through an etree starting from the document root or an arbitrary element. Paths are used with the Element object's Find* methods to locate and return desired elements.
A Path consists of a series of slash-separated "selectors", each of which may be modified by one or more bracket-enclosed "filters". Selectors are used to traverse the etree from element to element, while filters are used to narrow the list of candidate elements at each node.
Although etree Path strings are similar to XPath strings (https://www.w3.org/TR/1999/REC-xpath-19991116/), they have a more limited set of selectors and filtering options.
The following selectors are supported by etree Path strings:
. Select the current element. .. Select the parent of the current element. * Select all child elements of the current element. / Select the root element when used at the start of a path. // Select all descendants of the current element. tag Select all child elements with a name matching the tag.
The following basic filters are supported by etree Path strings:
[@attrib] Keep elements with an attribute named attrib. [@attrib='val'] Keep elements with an attribute named attrib and value matching val. [tag] Keep elements with a child element named tag. [tag='val'] Keep elements with a child element named tag and text matching val. [n] Keep the n-th element, where n is a numeric index starting from 1.
The following function filters are also supported:
[text()] Keep elements with non-empty text. [text()='val'] Keep elements whose text matches val. [local-name()='val'] Keep elements whose un-prefixed tag matches val. [name()='val'] Keep elements whose full tag exactly matches val. [namespace-prefix()='val'] Keep elements whose namespace prefix matches val. [namespace-uri()='val'] Keep elements whose namespace URI matches val.
Here are some examples of Path strings:
- Select the bookstore child element of the root element: /bookstore
- Beginning from the root element, select the title elements of all descendant book elements having a 'category' attribute of 'WEB':
//book[@category='WEB']/title
- Beginning from the current element, select the first descendant book element with a title child element containing the text 'Great Expectations':
.//book[title='Great Expectations'][1]
- Beginning from the current element, select all child elements of book elements with an attribute 'language' set to 'english':
./book/*[@language='english']
- Beginning from the current element, select all child elements of book elements containing the text 'special':
./book/*[text()='special']
- Beginning from the current element, select all descendant book elements whose title child element has a 'language' attribute of 'french':
.//book/title[@language='french']/..
- Beginning from the current element, select all book elements belonging to the http://www.w3.org/TR/html4/ namespace:
.//book[namespace-uri()='http://www.w3.org/TR/html4/']
Example ¶
Output: <book> <title>Great Expectations</title> <author>Charles Dickens</author> </book>
func CompilePath ¶
CompilePath creates an optimized version of an XPath-like string that can be used to query elements in an element tree.
func MustCompilePath ¶
MustCompilePath creates an optimized version of an XPath-like string that can be used to query elements in an element tree. Panics if an error occurs. Use this function to create Paths when you know the path is valid (i.e., if it's hard-coded).
type ProcInst ¶
A ProcInst represents an XML processing instruction.
func NewProcInst ¶
NewProcInst creates a parentless XML processing instruction.
type ReadSettings ¶
type ReadSettings struct { // CharsetReader to be passed to standard xml.Decoder. Default: nil. CharsetReader func(charset string, input io.Reader) (io.Reader, error) // Permissive allows input containing common mistakes such as missing tags // or attribute values. Default: false. Permissive bool // Entity to be passed to standard xml.Decoder. Default: nil. Entity map[string]string }
ReadSettings allow for changing the default behavior of the ReadFrom* methods.
type Token ¶
A Token is an empty interface that represents an Element, CharData, Comment, Directive, or ProcInst.
type WriteSettings ¶
type WriteSettings struct { // CanonicalEndTags forces the production of XML end tags, even for // elements that have no child elements. Default: false. CanonicalEndTags bool // CanonicalText forces the production of XML character references for // text data characters &, <, and >. If false, XML character references // are also produced for " and '. Default: false. CanonicalText bool // CanonicalAttrVal forces the production of XML character references for // attribute value characters &, < and ". If false, XML character // references are also produced for > and '. Default: false. CanonicalAttrVal bool // When outputting indented XML, use a carriage return and linefeed // ("\r\n") as a new-line delimiter instead of just a linefeed ("\n"). // This is useful on Windows-based systems. UseCRLF bool }
WriteSettings allow for changing the serialization behavior of the WriteTo* methods.