英文:
Custom xml decoder issue
问题
我有多个测试用例通过了,但是这个测试用例失败了。我在这里漏掉了什么导致解码器错误地读取了目标键的内容?
const respGenericFault1 = `<?xml version='1.0' encoding='UTF-8'?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode xsi:type="xsd:string">SOAP-ENV:Client</faultcode>
<faultstring xsi:type="xsd:string">Failed to validate</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>`
type Fault struct {
FaultCode, FaultString string
}
func (f Fault) Error() string {
return "Fault Code: '" + f.FaultCode + "' FaultString: '" + f.FaultString + "'"
}
func ParseFault(b []byte) error {
reader := bytes.NewReader(b)
d := xml.NewDecoder(reader)
var start xml.StartElement
fault := Fault{}
found := false
// iterate through the tokens
for {
tok, _ := d.Token()
if tok == nil {
break
}
// switch on token type
switch t := tok.(type) {
case xml.StartElement:
start = t.Copy()
fmt.Println(start.Name.Local)
case xml.CharData:
key := strings.ToLower(start.Name.Local)
// fault was found, capture the values and mark as found
if key == "faultcode" {
found = true
fault.FaultCode = string(t)
fmt.Printf("%#v\n", string(t))
} else if key == "faultstring" {
found = true
fault.FaultString = string(t)
}
}
}
if found {
return fault
}
return nil
}
func main() {
err := ParseFault([]byte(respGenericFault1))
fmt.Printf("%#v\n", err)
}
这是Playground的URL:http://play.golang.org/p/7PFPNsmast
英文:
I have multiple test cases which pass, however this one fails. What am I missing here that is causing the decoder read the content of my target keys incorrectly?
const respGenericFault1 = `<?xml version='1.0' encoding='UTF-8'?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode xsi:type="xsd:string">SOAP-ENV:Client</faultcode>
<faultstring xsi:type="xsd:string">Failed to validate</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>`
type Fault struct {
FaultCode, FaultString string
}
func (f Fault) Error() string {
return "Fault Code: '" + f.FaultCode + "' FaultString: '" + f.FaultString + "'"
}
func ParseFault(b []byte) error {
reader := bytes.NewReader(b)
d := xml.NewDecoder(reader)
var start xml.StartElement
fault := Fault{}
found := false
// iterate through the tokens
for {
tok, _ := d.Token()
if tok == nil {
break
}
// switch on token type
switch t := tok.(type) {
case xml.StartElement:
start = t.Copy()
fmt.Println(start.Name.Local)
case xml.CharData:
key := strings.ToLower(start.Name.Local)
// fault was found, capture the values and mark as found
if key == "faultcode" {
found = true
fault.FaultCode = string(t)
fmt.Printf("%#v\n", string(t))
} else if key == "faultstring" {
found = true
fault.FaultString = string(t)
}
}
}
if found {
return fault
}
return nil
}
func main() {
err := ParseFault([]byte(respGenericFault1))
fmt.Printf("%#v\n", err)
}
Here is the playground url: http://play.golang.org/p/7PFPNsmast
答案1
得分: 2
你的代码成功捕获了faultstring
和faultcode
,但是接着无意中用包含标签之间空白的xml.CharData
覆盖了它们。
这里是修复后的版本:http://play.golang.org/p/s1aFFYtwcX。注释掉第52行可以看到故障模式。
另外,你可以使用encoding/xml Unmarshal
将XML直接解析为结构体。参考:http://play.golang.org/p/lOsZRUJ63B
英文:
Your code successfully captures the faultstring
and faultcode
, but then unintentionally overwrites it with xml.CharData
containing the whitespace between tags.
Here is a fixed version: http://play.golang.org/p/s1aFFYtwcX . Comment out line 52 to see the failure mode.
Alternatively, you can use encoding/xml Unmarshal
to parse the XML directly into a struct. See http://play.golang.org/p/lOsZRUJ63B
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论