GolangStudy/src/study/day9Interface/xml.go

67 lines
1.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// Xmlselect prints the text of selected elements of an XML document.
package main
import (
"encoding/xml"
"fmt"
"io"
"os"
"strings"
)
func main() {
dec := xml.NewDecoder(os.Stdin)
var stack []string // stack of element names
for {
tok, err := dec.Token()
if err == io.EOF {
break
} else if err != nil {
fmt.Fprintf(os.Stderr, "xmlselect: %v\n", err)
os.Exit(1)
}
switch tok := tok.(type) {
case xml.StartElement:
stack = append(stack, tok.Name.Local) // push
case xml.EndElement:
stack = stack[:len(stack)-1] // pop
case xml.CharData:
if containsAll(stack, os.Args[1:]) {
fmt.Printf("%s: %s\n", strings.Join(stack, " "), tok)
}
}
}
}
// containsAll reports whether x contains the elements of y, in order.
func containsAll(x, y []string) bool {
for len(y) <= len(x) {
if len(y) == 0 {
return true
}
if x[0] == y[0] {
y = y[1:]
}
x = x[1:]
}
return false
}
// xmlselect
//
// 扩展xmlselect程序以便让元素不仅可以通过名称选择也可以通过它们CSS风格的属性进行选择。
// 例如一个像这样
// <div id="page" class="wide">
// 的元素可以通过id选择器#page或者class选择器.wide进行选择。
// 你可以选择任意多个属性,但是只有当所有的属性都匹配时才能选择成功。
// 例如选择id为page且class为wide的元素应该使用#page.wide选择器。
// 你需要为StartEnd元素增加一个Data域用于保存元素的所有属性。
// 可以使用encoding/xml包的Unmarshal函数来解析元素的属性。
// 你需要定义一个新类型来保存属性,例如
// type Attr []xml.Attr
// 然后在StartElement解码的时候将属性保存到Data域中。
// 你可以使用strings.SplitN函数来分割属性strings.HasPrefix函数来查找前缀
// strings.TrimPrefix函数来去掉前缀。
// 你需要为css选择器增加一个新的case分支然后在栈中查找匹配的元素。
//