自定义 XML 解码器问题

huangapple go评论93阅读模式
英文:

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

你的代码成功捕获了faultstringfaultcode,但是接着无意中用包含标签之间空白的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

huangapple
  • 本文由 发表于 2014年10月6日 23:34:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/26219703.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定