<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 7.14. 示例: 基于標記的XML解碼 第4.5章節展示了如何使用encoding/json包中的Marshal和Unmarshal函數來將JSON文檔轉換成Go語言的數據結構。encoding/xml包提供了一個相似的API。當我們想構造一個文檔樹的表示時使用encoding/xml包會很方便,但是對于很多程序并不是必須的。encoding/xml包也提供了一個更低層的基于標記的API用于XML解碼。在基于標記的樣式中,解析器消費輸入并產生一個標記流;四個主要的標記類型-StartElement,EndElement,CharData,和Comment-每一個都是encoding/xml包中的具體類型。每一個對(\*xml.Decoder).Token的調用都返回一個標記。 這里顯示的是和這個API相關的部分: <u><i>encoding/xml</i></u> ```go package xml type Name struct { Local string // e.g., "Title" or "id" } type Attr struct { // e.g., name="value" Name Name Value string } // A Token includes StartElement, EndElement, CharData, // and Comment, plus a few esoteric types (not shown). type Token interface{} type StartElement struct { // e.g., <name> Name Name Attr []Attr } type EndElement struct { Name Name } // e.g., </name> type CharData []byte // e.g., <p>CharData</p> type Comment []byte // e.g., <!-- Comment --> type Decoder struct{ /* ... */ } func NewDecoder(io.Reader) *Decoder func (*Decoder) Token() (Token, error) // returns next Token in sequence ``` 這個沒有方法的Token接口也是一個可識別聯合的例子。傳統的接口如io.Reader的目的是隱藏滿足它的具體類型的細節,這樣就可以創造出新的實現:在這個實現中每個具體類型都被統一地對待。相反,滿足可識別聯合的具體類型的集合被設計為確定和暴露,而不是隱藏。可識別聯合的類型幾乎沒有方法,操作它們的函數使用一個類型分支的case集合來進行表述,這個case集合中每一個case都有不同的邏輯。 下面的xmlselect程序獲取和打印在一個XML文檔樹中確定的元素下找到的文本。使用上面的API,它可以在輸入上一次完成它的工作而從來不要實例化這個文檔樹。 <u><i>gopl.io/ch7/xmlselect</i></u> ```go // 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 } ``` main函數中的循環每遇到一個StartElement時,它把這個元素的名稱壓到一個棧里,并且每次遇到EndElement時,它將名稱從這個棧中推出。這個API保證了StartElement和EndElement的序列可以被完全的匹配,甚至在一個糟糕的文檔格式中。注釋會被忽略。當xmlselect遇到一個CharData時,只有當棧中有序地包含所有通過命令行參數傳入的元素名稱時,它才會輸出相應的文本。 下面的命令打印出任意出現在兩層div元素下的h2元素的文本。它的輸入是XML的說明文檔,并且它自己就是XML文檔格式的。 ``` $ 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 ... ``` **練習 7.17:** 擴展xmlselect程序以便讓元素不僅可以通過名稱選擇,也可以通過它們CSS風格的屬性進行選擇。例如一個像這樣 ``` html <div id="page" class="wide"> ``` 的元素可以通過匹配id或者class,同時還有它的名稱來進行選擇。 **練習 7.18:** 使用基于標記的解碼API,編寫一個可以讀取任意XML文檔并構造這個文檔所代表的通用節點樹的程序。節點有兩種類型:CharData節點表示文本字符串,和 Element節點表示被命名的元素和它們的屬性。每一個元素節點有一個子節點的切片。 你可能發現下面的定義會對你有幫助。 ```go import "encoding/xml" type Node interface{} // CharData or *Element type CharData string type Element struct { Type xml.Name Attr []xml.Attr Children []Node } ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看