首页 > 解决方案 > 使用 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}]}

我怎样才能捕捉到这些错误并抛出错误?

标签: xmlparsinggoexceptionmisspelling

解决方案


如果你去 encoding/xml 的文档

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

有一个编写自定义 Marshal/Unmarshal 的例子,你只需要实现 Unmarshaler 接口

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


推荐阅读