使用Go解析时,如何检查输入XML中的错误?

问题描述

我是golang的初学者,正在编写XML解析器。

我的目标是要包括检查xml文件格式是否正确,检查括号和元素和属性的拼写错误的单词。如果缺少括号或单词拼写错误代码可能会引发异常,通知用户纠正错误

让我们以xml文件example.xml的具体示例为例:

<?xml version="1.0" encoding="utf-8"?>

<servers version="1">
    <server>
        <model name="Cisco" type="modelA"></model>
        <serverName>Tokyo_VPN</serverName>
        <serverIP>127.0.0.1</serverIP>
    </server>
    <server>
        <model name="Dell" type="modelB"></model>
        <serverName>Moscow_VPN</serverName>
        <serverIP>127.0.0.2</serverIP>
    </server>
</servers>

使用标准的Go软件包"encoding/xml",可以很容易地定义结构并解析XML,如下所示:

package main

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

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

type server struct {
    XMLName    xml.Name `xml:"server"`
    Model      model    `xml:"model"`
    ServerName string   `xml:"serverName"`
    ServerIP   string   `xml:"serverIP"`
}

type model struct {
    XMLName    xml.Name   `xml:"model"` 
    Name       string     `xml:"name,attr"`
    Type       string     `xml:"type,attr"`  
}


func main() {

    // open the xml file
    file,err := os.Open("toy.xml")  
    if err != nil {
        fmt.Printf("error: %v",err)
        return
    }
    defer file.Close()

    // read the opened xmlFile as a byte array.
    byteValue,_ := IoUtil.ReadAll(file)

    var allservers Servers

    err = xml.Unmarshal(byteValue,&allservers)
    if err != nil {
        fmt.Printf("error: %v",err)
        return
    }

    fmt.Println(allservers)
}

错误,例如缺少括号

<model name="Cisco" type="modelA"></model

或拼写错误属性/元素,例如

<serverNammme>Moscow_VPN</serverName>

,这些错误是通过XML语法错误捕获的。

虽然可能还会发生其他错误。例如,属性的拼写错误的单词:

<model namMMe="Cisco" typeE="modelA"></model>

尽管这是有效的XML格式,但我想将其视为错误,因为(出于我的目的)这些是输入XML文件中的拼写错误,应予以纠正。

内容将被解析为以下内容

{{ servers} 1 [{{ server} {{ model}  } Tokyo_VPN 127.0.0.1} {{ server} {{ model} Dell modelB} Moscow_VPN 127.0.0.2}]}

我该如何捕捉这些错误并抛出错误

解决方法

如果您要查看encoding / xml文档

https://golang.org/pkg/encoding/xml/#Unmarshal

有一个示例,用于编写自定义的Marshal / Unmarshal,您只需要实现Unmarshaler接口

因此,您自定义的Unmarshaler可以在取消编组并返回错误时检查值