diff --git a/examples.txt b/examples.txt index 22a2c3b..880802f 100644 --- a/examples.txt +++ b/examples.txt @@ -46,6 +46,7 @@ String Functions String Formatting Regular Expressions JSON +XML Time Epoch Time Formatting / Parsing diff --git a/examples/xml/xml.go b/examples/xml/xml.go index f172bc6..e545106 100644 --- a/examples/xml/xml.go +++ b/examples/xml/xml.go @@ -1,3 +1,6 @@ +// Go offers built-in support for XML and XML-like +// formats with the `encoding.xml` package. + package main import ( @@ -5,15 +8,22 @@ import ( "fmt" ) +// This type will be mapped to XML. Similarly to the +// JSON examples, field tags contain directives for the +// encoder and decoder. Here we use some special features +// of the XML package: the `XMLName` field name dictates +// the name of the XML element representing this struct; +// `id,attr` means that the `Id` field is an XML +// _attribute_ rather than a nested element. type Plant struct { - XMLName xml.Name `xml:"fruit"` + XMLName xml.Name `xml:"plant"` Id int `xml:"id,attr"` Name string `xml:"name"` Origin []string `xml:"origin"` } func (p Plant) String() string { - return fmt.Sprintf("Fruit id=%v, name=%v, origin=%v", + return fmt.Sprintf("Plant id=%v, name=%v, origin=%v", p.Id, p.Name, p.Origin) } @@ -21,12 +31,39 @@ func main() { coffee := &Plant{Id: 27, Name: "Coffee"} coffee.Origin = []string{"Ethiopia", "Brazil"} + // Emit XML representing our plant; using + // `MarshalIndent` to produce a more + // human-readable output. out, _ := xml.MarshalIndent(coffee, " ", " ") fmt.Println(string(out)) + // To add a generic XML header to the output, append + // it explicitly. + fmt.Println(xml.Header + string(out)) + + // Use `Unmarhshal` to parse a stream of bytes with XML + // into a data structure. If the XML is malformed or + // cannot be mapped onto Plant, a descriptive error + // will be returned. var p Plant if err := xml.Unmarshal(out, &p); err != nil { panic(err) } fmt.Println(p) + + tomato := &Plant{Id: 81, Name: "Tomato"} + tomato.Origin = []string{"Mexico", "California"} + + // The `parent>child>plant` field tag tells the encoder + // to nest all `plant`s under `...` + type Nesting struct { + XMLName xml.Name `xml:"nesting"` + Plants []*Plant `xml:"parent>child>plant"` + } + + nesting := &Nesting{} + nesting.Plants = []*Plant{coffee, tomato} + + out, _ = xml.MarshalIndent(nesting, " ", " ") + fmt.Println(string(out)) } diff --git a/examples/xml/xml.hash b/examples/xml/xml.hash new file mode 100644 index 0000000..104125d --- /dev/null +++ b/examples/xml/xml.hash @@ -0,0 +1,2 @@ +18ada773098bca38778a58b438d6af70529f18b0 +qd9Ii_3AW0s diff --git a/examples/xml/xml.sh b/examples/xml/xml.sh new file mode 100644 index 0000000..0e8d2cd --- /dev/null +++ b/examples/xml/xml.sh @@ -0,0 +1,29 @@ +$ go run xml.go + + Coffee + Ethiopia + Brazil + + + + Coffee + Ethiopia + Brazil + +Plant id=27, name=Coffee, origin=[Ethiopia Brazil] + + + + + Coffee + Ethiopia + Brazil + + + Tomato + Mexico + California + + + + diff --git a/public/index.html b/public/index.html index 8c83d38..74ff261 100644 --- a/public/index.html +++ b/public/index.html @@ -119,6 +119,8 @@
  • JSON
  • +
  • XML
  • +
  • Time
  • Epoch
  • diff --git a/public/json b/public/json index fb7b9c8..1cc92b7 100644 --- a/public/json +++ b/public/json @@ -14,7 +14,7 @@ if (e.key == "ArrowRight") { - window.location.href = 'time'; + window.location.href = 'xml'; } } @@ -392,7 +392,7 @@ for more.

    - Next example: Time. + Next example: XML.

    +

    Go by Example: XML

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    Go offers built-in support for XML and XML-like +formats with the encoding.xml package.

    + +
    + + +
    + + + + + +
    package main
    +
    + +
    + + + +
    import (
    +    "encoding/xml"
    +    "fmt"
    +)
    +
    + +
    +

    This type will be mapped to XML. Similarly to the +JSON examples, field tags contain directives for the +encoder and decoder. Here we use some special features +of the XML package: the XMLName field name dictates +the name of the XML element representing this struct; +id,attr means that the Id field is an XML +attribute rather than a nested element.

    + +
    + +
    type Plant struct {
    +    XMLName xml.Name `xml:"plant"`
    +    Id      int      `xml:"id,attr"`
    +    Name    string   `xml:"name"`
    +    Origin  []string `xml:"origin"`
    +}
    +
    + +
    + + + +
    func (p Plant) String() string {
    +    return fmt.Sprintf("Plant id=%v, name=%v, origin=%v",
    +        p.Id, p.Name, p.Origin)
    +}
    +
    + +
    + + + +
    func main() {
    +    coffee := &Plant{Id: 27, Name: "Coffee"}
    +    coffee.Origin = []string{"Ethiopia", "Brazil"}
    +
    + +
    +

    Emit XML representing our plant; using +MarshalIndent to produce a more +human-readable output.

    + +
    + +
        out, _ := xml.MarshalIndent(coffee, " ", "  ")
    +    fmt.Println(string(out))
    +
    + +
    +

    To add a generic XML header to the output, append +it explicitly.

    + +
    + +
        fmt.Println(xml.Header + string(out))
    +
    + +
    +

    Use Unmarhshal to parse a stream of bytes with XML +into a data structure. If the XML is malformed or +cannot be mapped onto Plant, a descriptive error +will be returned.

    + +
    + +
        var p Plant
    +    if err := xml.Unmarshal(out, &p); err != nil {
    +        panic(err)
    +    }
    +    fmt.Println(p)
    +
    + +
    + + + +
        tomato := &Plant{Id: 81, Name: "Tomato"}
    +    tomato.Origin = []string{"Mexico", "California"}
    +
    + +
    +

    The parent>child>plant field tag tells the encoder +to nest all plants under <parent><child>...

    + +
    + +
        type Nesting struct {
    +        XMLName xml.Name `xml:"nesting"`
    +        Plants  []*Plant `xml:"parent>child>plant"`
    +    }
    +
    + +
    + + + +
        nesting := &Nesting{}
    +    nesting.Plants = []*Plant{coffee, tomato}
    +
    + +
    + + + +
        out, _ = xml.MarshalIndent(nesting, " ", "  ")
    +    fmt.Println(string(out))
    +}
    +
    + +
    + + + + + + + + +
    + + + +
    $ go run xml.go
    + <plant id="27">
    +   <name>Coffee</name>
    +   <origin>Ethiopia</origin>
    +   <origin>Brazil</origin>
    + </plant>
    +<?xml version="1.0" encoding="UTF-8"?>
    + <plant id="27">
    +   <name>Coffee</name>
    +   <origin>Ethiopia</origin>
    +   <origin>Brazil</origin>
    + </plant>
    +Plant id=27, name=Coffee, origin=[Ethiopia Brazil]
    + <nesting>
    +   <parent>
    +     <child>
    +       <plant id="27">
    +         <name>Coffee</name>
    +         <origin>Ethiopia</origin>
    +         <origin>Brazil</origin>
    +       </plant>
    +       <plant id="81">
    +         <name>Tomato</name>
    +         <origin>Mexico</origin>
    +         <origin>California</origin>
    +       </plant>
    +     </child>
    +   </parent>
    + </nesting>
    +
    + +
    + + +

    + Next example: Time. +

    + + +
    + +