提问人:ankit jain 提问时间:7/18/2023 最后编辑:egleaseankit jain 更新时间:8/31/2023 访问量:48
我需要使用 golang 验证输入字符串是否采用正确的 xml 格式。我的代码没有验证它是否具有正确的封闭标记
I need to validate whether a input string is in proper xml format using golang. My code doesn't validate if it has proper enclosing tags or not
问:
if err := xml.Unmarshal([]byte(str), new(interface{})); err != nil {
ve.Add("eav", "must be a valid xml")
}
但是当我传递一个字符串时,它不会抛出错误,例如
<to>Tove</to>
<from>Jani</from>
我希望它抛出错误。
我试过这个代码
if err := xml.Unmarshal([]byte(str), new(interface{})); err != nil {
ve.Add("eav", "must be a valid xml")
}
答:
0赞
Marrow父
8/31/2023
#1
不检查 xml 格式是否正确似乎很奇怪 - 毕竟,格式不正确的 xml 根本不是真正的 xml。xml.Unmarshal
但是,使用它可以检查一些格式不正确的问题(例如多个或缺少根元素)......xml.Decoder
package main
import (
"encoding/xml"
"errors"
"fmt"
"io"
"strings"
)
func main() {
testCases := map[string]string{
"valid": `<root><to>Tove</to><from>Jani</from></root>`,
"multiple roots": `<to>Tove</to><from>Jani</from>`,
"empty": ``,
"no root": `<?xml version='1.0'?>`,
"valid xml decl": `<?xml version='1.0'?><root/>`,
"invalid pi name": `<root><?Xml pi name cannot be xml?></root>`,
"xml decl inside root": `<root><?xml version='1.0'?></root>`,
"multiple xml decls": `<?xml version='1.0'?><?xml version='1.0'?><root/>`,
"comment before xml decl": `<!-- comment --><?xml version='1.0'?><root/>`,
"cdata before xml decl": `<![CDATA[text]]><?xml version='1.0'?><root/>`,
}
for name, str := range testCases {
if err := checkXmlWellFormed(strings.NewReader(str)); err != nil {
fmt.Printf("'%s' error: %s\n", name, err.Error())
} else {
fmt.Printf("'%s' is well-formed xml\n", name)
}
}
}
func checkXmlWellFormed(r io.Reader) error {
d := xml.NewDecoder(r)
d.Strict = true
var err error
var token xml.Token
var finalErr error
depth := 0
rootFound := false
xmlDeclFound := false
pastProlog := false
for err == nil && finalErr == nil {
token, err = d.Token()
if err == nil {
switch tt := token.(type) {
case xml.StartElement:
pastProlog = true
if depth == 0 {
if rootFound {
finalErr = errors.New("too many root elements")
} else {
rootFound = true
}
}
depth++
case xml.EndElement:
pastProlog = true
depth--
case xml.ProcInst:
if tt.Target == "xml" {
if xmlDeclFound {
finalErr = errors.New("multiple xml declarations")
} else if pastProlog {
finalErr = errors.New("xml declaration must be first")
}
xmlDeclFound = true
} else if strings.ToUpper(tt.Target) == "XML" {
finalErr = fmt.Errorf("invalid processing instruction name '%s'", tt.Target)
}
case xml.CharData:
if depth < 1 {
finalErr = errors.New("character data outside element")
}
pastProlog = true
default:
pastProlog = true
}
} else if err != io.EOF {
finalErr = err
}
}
if finalErr == nil && !rootFound {
finalErr = errors.New("no root element")
}
return finalErr
}
通过适度的努力,还可以检查足够的命名空间声明 - 其他/不检查:(的东西xml.Decoder
xml.Unmarshal
评论