golang中XML文件的处理
在golang中 包"encoding/xml" 提供了对xml文件的解析。
有两种常见方式对其解析,
举个栗子
package main
import (
"fmt"
"io/ioutil"
"errors"
"os"
"log"
"flag"
"os/exec"
"regexp"
"strings"
"encoding/xml"
"bytes"
)
manifest := projectDir + "/AndroidManifest.xml"
content, err := ioutil.ReadFile(manifest)
if err != nil {
log.Fatal(err)
}
//inputReader := strings.NewReader(content)
//decoder := xml.NewDecoder(inputReader)
decoder := xml.NewDecoder(bytes.NewBuffer(content))
for t, err := decoder.Token(); err == nil; t, err = decoder.Token() {
switch token := t.(type) {
// 处理元素开始(标签)
case xml.StartElement:
name := token.Name.Local
fmt.Printf("Token name: %s\n", name)
for _, attr := range token.Attr {
attrName := attr.Name.Local
attrValue := attr.Value
fmt.Printf("An attribute is: %s %s\n", attrName, attrValue)
}
// 处理元素结束(标签)
case xml.EndElement:
fmt.Printf("Token of '%s' end\n", token.Name.Local)
// 处理字符数据(这里就是元素的文本)
case xml.CharData:
content := string([]byte(token))
fmt.Printf("This is the content: %v\n", content)
default:
// ...
}
}
fmt.Printf("xml success!\n")
缺点: 兼容性不好,而且要定义很多struct
有点,转化后的数据,看起来清晰
举个栗子
用栗子说话
package main
//import "github.com/gin-gonic/gin"
import (
//"encoding/json"
"fmt"
"io/ioutil"
//"net/http"
"log"
"encoding/xml"
"os"
)
const Header string = `<?xml version="1.0" encoding="utf-8" standalone="no"?>` + "\n"
type manifest struct {
Xmlns xml.Attr `xml:"android,attr"`
InstallLocation xml.Attr `xml:"installLocation,attr"`
Package xml.Attr `xml:"package,attr"`
PlatformBuildVersionCode xml.Attr `xml:"platformBuildVersionCode,attr"`
PlatformBuildVersionName xml.Attr `xml:"platformBuildVersionName,attr"`
SupportsScreens SupportsScreens `xml:"supports-screens"`
}
type SupportsScreens struct {
AnyDensity xml.Attr `xml:"anyDensity,attr"`
LargeScreens xml.Attr `xml:"largeScreens,attr"`
NormalScreens xml.Attr `xml:"normalScreens,attr"`
SmallScreens xml.Attr `xml:"smallScreens,attr"`
XlargeScreens xml.Attr `xml:"xlargeScreens,attr"`
}
func NewManifest(filename string)(manifest) {
content, err := ioutil.ReadFile(filename)
if err != nil {
log.Fatal(err)
}
var result manifest
err = xml.Unmarshal(content, &result)
if err != nil {
log.Fatal(err)
}
//log.Println(result)
//log.Println(result.Persons[0].Name)
return result
}
func main() {
//xml.Attr
result := NewManifest("project/name/AndroidManifest.xml")
fmt.Printf("-->%+v\n",result)
xmlOutPut, outPutErr := xml.MarshalIndent(result, "", "")
if outPutErr == nil {
//加入XML头
headerBytes := []byte(xml.Header)
//拼接XML头和实际XML内容
xmlOutPutData := append(headerBytes, xmlOutPut...)
//写入文件
ioutil.WriteFile("test.xml", xmlOutPutData, os.ModeAppend)
fmt.Println("OK~")
} else {
fmt.Println(outPutErr)
}
}
(标准库encoding/xml文档有详细的说明)
xml:”myperson”
试试,会报错:expected element typebut havedata),那么,字符数据会被累加到struct中第一个有tag为”,chardata”的字段。struct字段的类型可以是string或[]byte。如果没有这样的字段,字符数据会被丢弃。如上面的Interests可以再定义一个类型Interest:
type Interest struct {
Inter string xml:”,chardata”
}
Interests 中相应的改为:Interest []Interest
当然这个例子中这种方式有些啰嗦。
12 . 如果一个struct字段的tag定义为”-“,则Unmarshal不会给它赋值