packagexmltypeNamestruct { Local string// e.g., "Title" or "id"}typeAttrstruct { // e.g., name="value" Name Name Value string}// A Token includes StartElement, EndElement, CharData,// and Comment, plus a few esoteric types (not shown).typeTokeninterface{}typeStartElementstruct { // e.g., <name> Name Name Attr []Attr}typeEndElementstruct { Name Name } // e.g., </name>typeCharData []byte// e.g., <p>CharData</p>typeComment []byte// e.g., <!-- Comment -->typeDecoderstruct{ /*...*/ }funcNewDecoder(io.Reader) *Decoderfunc (*Decoder) Token() (Token, error) // returns next Token in sequence
// Xmlselect prints the text of selected elements of an XML document.packagemainimport ("encoding/xml""fmt""io""os""strings")funcmain() { dec := xml.NewDecoder(os.Stdin)var stack []string// stack of element namesfor { tok, err := dec.Token()if err == io.EOF {break } elseif err !=nil { fmt.Fprintf(os.Stderr, "xmlselect: %v\n", err) os.Exit(1) }switch tok := tok.(type) {casexml.StartElement: stack =append(stack, tok.Name.Local) // pushcasexml.EndElement: stack = stack[:len(stack)-1] // popcasexml.CharData:ifcontainsAll(stack, os.Args[1:]) { fmt.Printf("%s: %s\n", strings.Join(stack, " "), tok) } } }}// containsAll reports whether x contains the elements of y, in order.funccontainsAll(x, y []string) bool {forlen(y) <=len(x) {iflen(y) ==0 {returntrue }if x[0] == y[0] { y = y[1:] } x = x[1:] }returnfalse}
$ go build gopl.io/ch1/fetch
$ ./fetch http://www.w3.org/TR/2006/REC-xml11-20060816 |
./xmlselect div div h2
html body div div h2: 1 Introduction
html body div div h2: 2 Documents
html body div div h2: 3 Logical Structures
html body div div h2: 4 Physical Structures
html body div div h2: 5 Conformance
html body div div h2: 6 Notation
html body div div h2: A References
html body div div h2: B Definitions for Character Normalization
...