golang的xml、json解析

xml

golang的xml处理主要应用Unmarshal、Marshal方法实现,解析一个xml到struct如下,首先是xml文件:

<?xml version="1.0" encoding="utf-8"?>
<servers version="1.0">
    <!--测试注释server-->
    <server desc="s1">
        <serverName>Shanghai_VPN</serverName>
        <serverIP>127.0.0.1</serverIP>
    </server>
    <server desc="s2">
        <!---->
        <serverName>Beijing_VPN</serverName>
        <serverIP>127.0.0.2</serverIP>
    </server>
</servers>

下面记录下主要代码:

// parse2xml project main.go
package main

import (
    "encoding/xml"
    "fmt"
    "io/ioutil"
    "os"
)

type Recurlyservers struct {
    XMLName     xml.Name `xml:"servers"`
    Version     string   `xml:"version,attr"`
    Svs         []server `xml:"server"`
    Description string   `xml:",innerxml"`
}

type server struct {
    XMLName    xml.Name `xml:"server"`
    Desc       string   `xml:"desc,attr"`
    ServerName string   `xml:"serverName"`
    ServerIP   string   `xml:"serverIP"`
    TestDesc   string   `xml:",innerxml"`
}

func main() {
    
    file, err := os.Open("servers.xml")
    if err != nil {
        fmt.Printf("%s", err.Error())
        panic(err)
    }
    defer file.Close()
    data, err := ioutil.ReadAll(file)
    v := Recurlyservers{}
    err = xml.Unmarshal(data, &v)
    if err != nil {
        fmt.Printf("%s", err.Error())
        panic(err)
    }
    fmt.Printf("%#v", v)
}

打印结果:

可以发现Unmarshal解析时的一些规则:

1、解析使用struct的tag配置,通过底层反射实现

2、类型为xml.Name的struct字段XMLName对应的是xml中的“父”节点名称,如servers

3、*,attr对应的为当前父节点上的属性名称,如version,attr,对应的便是xml文件中servers节点的version属性

4、tag中仅写一个名称如serverName,表示serverName为节点名称

5、对于某个struct中,innerxml的tag标注,该struct的属性对应的数据为该struct相应的XMLName对应的xml下的所有内容,比如TestDesc对应的为server节点下的所有内容,Description对应的便是servers下的所有内容

由struct生成对应的xml,方法如下:

// struct2xmll project main.go
package main

import (
    "encoding/xml"
    "fmt"
    "os"
)

type Servers struct {
    XMLName xml.Name `xml:"servers"`
    Version string   `xml:"version,attr"`
    Svs     []server `xml:"server"`
}

type server struct {
    ServerName string `xml:"serverName"`
    ServerIP   string `xml:"serverIP"`
}

func main() {
    v := &Servers{Version: "1.0"}
    v.Svs = append(v.Svs, server{"Shanghai_VPN", "127.0.0.1"})
    v.Svs = append(v.Svs, server{"Beijing_VPN", "127.0.0.1"})
    output, err := xml.MarshalIndent(v, " ", " ")
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    os.Stdout.Write([]byte(xml.Header))
    file, err := os.Create("servers.xml")
    file.Write([]byte(xml.Header))
    file.Write(output)
}

生成的xml文档:

json

将json字符串解析为struct:

// jsonparse project main.go
package main

import (
    "encoding/json"
    "fmt"
)

type Server struct {
    ServerName string `json:"serverName"`
    ServerIP   string `json:"serverIP"`
}

type Serversslice struct {
    Servers []Server `json:"servers"`
}

func main() {
    var s Serversslice
    str := `{"servers":[{"serverName":"Shanghai_VPN","serverIP":"127.0.0.1"},{"serverName":"Beijing_VPN","serverIP":"192.168.20.132"}]}`
    json.Unmarshal([]byte(str), &s)
    fmt.Printf("%#v", s)
}

结果:

将一个struct解析为json如下:

package main

import (
    "encoding/json"
    "fmt"
)

type Server struct {
    serverName string `json:"serverName"`
    ServerIP   string `json:"serverIP"`
}

type ServersSlice struct {
    Servers []Server `json:"servers"`
    Desc    string   `json:"desc"`
}

func main() {
    servers := []Server{{serverName: "admin", ServerIP: "192.168.20.131"}, {serverName: "admin1", ServerIP: "192.168.20.132"}}
    desc := "描述部分"
    var ss ServersSlice
    ss.Desc = desc
    ss.Servers = servers
    js, _ := json.Marshal(ss)
    fmt.Printf("Json: %s", js)
}

结果:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏IT笔记

JAVA实现微信退款报错unexpected end of file from server

前几天做了微信扫码支付,同事说把退款接口也做了吧,然后就根据申请退款文档,把支付的方法拿过来用了,结果抛出了这样一个问题 unexpected end of f...

3739
来自专栏博客园

mongo 监听指定语句

262
来自专栏c#开发者

MSMQ突破4M限制的方法

    在默认情况下msmq 3.0(windows xp ,windows 2003)最大单个消息(Message size)大小4M;(包括正文和全部指定属...

2794
来自专栏大内老A

我的WCF之旅(2):Endpoint Overview

WCF实际上是构建了一个框架,这个框架实现了在互联系统中各个Application之间如何通信。使得Developers和Architect在构建分布式系统中,...

1817
来自专栏Golang语言社区

如果裸写一个goroutine pool

引言 在上文中,我说到golang的原生http server处理client的connection的时候,每个connection起一个goroutine,这...

4016
来自专栏菩提树下的杨过

ExtJs学习笔记(20)-利用ExtJs的Ajax与服务端WCF交互

ExtJs是一套非常不错的javascript UI库(第一次接触ExtJs的,可到官方网站http://www.extjs.com/deploy/dev/ex...

2037
来自专栏大内老A

WCF后续之旅(16): 消息是如何分发到Endpoint的--消息筛选(Message Filter)

在介绍终结点的ListenUriMode时,我们提到了两个特殊的对象ChannelDispatcher和ChannelListener。这两个对象在整个WCF的...

1857
来自专栏函数式编程语言及工具

Akka(3): Actor监管 - 细述BackoffSupervisor

    在上一篇讨论中我们谈到了监管:在Akka中就是一种直属父子监管树结构,父级Actor负责处理直属子级Actor产生的异常。当时我们把BackoffSup...

2306
来自专栏林德熙的博客

dotnet core 黑科技·String.IndexOf 性能

本文来告诉大家 dotnet core 里面使用的黑科技,如何提高String.IndexOf(char)的性能

741
来自专栏斑斓

Spray中的Authentication和JMeter测试

Spray Authentication 在Spray中,如果需要对REST API添加认证,可以使用Spray提供的Authenticate功能。本质上,Au...

3519

扫码关注云+社区