Golang解析海康ANPR相机XML遇非法字符,求解决方案
解决Golang解析海康ANPR相机告警XML时的非法字符问题
方案一:直接忽略plateCharBelieve字段
如果不需要该字段的置信度数据,最简单的方式是在定义XML解析结构体时,给该字段的标签设置为"-",让Golang的XML解析器直接跳过该字段:
type AlarmEvent struct { // 其他字段示例 PlateNumber string `xml:"plateNumber"` // 忽略plateCharBelieve字段 PlateCharBelieve string `xml:"-"` // 其他字段... }
这样xml.Unmarshal时会完全跳过该字段,不会触发非法字符的解析错误。
方案二:自定义解码器解析为整数数组
如果需要获取置信度数据,可以通过实现xml.Unmarshaler接口自定义解析逻辑,同时关闭严格模式忽略非法字符:
1. 定义自定义类型
先定义一个用于存储置信度的切片类型:
import ( "encoding/xml" "strconv" "strings" ) type PlateConfidence []int
2. 实现UnmarshalXML接口
给自定义类型实现xml.Unmarshaler方法,在方法中关闭严格模式、读取原始内容并转换为整数:
func (pc *PlateConfidence) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { // 关闭严格模式,忽略XML中的非法控制字符 d.Strict(false) // 读取字段的原始字符串内容 var rawContent string if err := d.DecodeElement(&rawContent, &start); err != nil { return err } // 按逗号分割字符串并转换为整数 parts := strings.Split(rawContent, ",") confidences := make([]int, 0, len(parts)) for _, part := range parts { trimmed := strings.TrimSpace(part) num, err := strconv.Atoi(trimmed) if err != nil { // 遇到无效值可选择跳过或返回错误,这里选择跳过 continue } // 过滤0-100范围外的无效值 if num >= 0 && num <= 100 { confidences = append(confidences, num) } } *pc = confidences return nil }
3. 在结构体中使用自定义类型
修改告警事件结构体,将plateCharBelieve字段类型设为自定义的PlateConfidence:
type AlarmEvent struct { // 其他字段... PlateNumber string `xml:"plateNumber"` PlateCharBelieve PlateConfidence `xml:"plateCharBelieve"` // 其他字段... }
可选:预处理XML数据过滤非法字符
如果不想修改解析逻辑,也可以先对原始XML数据进行预处理,过滤掉非法控制字符后再解析:
import "regexp" // 匹配XML非法控制字符的正则 var invalidXMLChars = regexp.MustCompile(`[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]`) func cleanXMLData(rawXML []byte) []byte { // 将非法字符替换为空字符串 return invalidXMLChars.ReplaceAll(rawXML, []byte("")) } // 使用示例: // rawData := []byte("你的XML原始数据") // cleanedData := cleanXMLData(rawData) // var event AlarmEvent // xml.Unmarshal(cleanedData, &event)
内容的提问来源于stack exchange,提问作者lukerobbo
相关产品推荐
相关产品推荐

