反序列化转义的XML

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

Unmarshalling escaped XML

问题

在Go语言中,您可以如何解码这个XML响应?我尝试在我的Answer结构体上构建一个自定义的Unmarshal方法,但是运气不太好。

<?xml version="1.0"?>
<GetAssignmentResponse>
    <Answer>&lt;?xml version="1.0" encoding="UTF-8" standalone="no"?&gt;
        &lt;QuestionFormAnswers xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2005-10-01/QuestionFormAnswers.xsd"&gt;
        &lt;Answer&gt;
        &lt;QuestionIdentifier&gt;Q1HasEvents&lt;/QuestionIdentifier&gt;
        &lt;FreeText&gt;no&lt;/FreeText&gt;
        &lt;/Answer&gt;
        &lt;/QuestionFormAnswers&gt;
    </Answer>
</GetAssignmentResponse>
英文:

In Go, how would I go about decoding this XML response? I've tried building a custom UnMarshal method on my Answer struct, but I'm not having much luck.

&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;GetAssignmentResponse&gt;
	&lt;Answer&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&amp;gt;
		&amp;lt;QuestionFormAnswers xmlns=&quot;http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2005-10-01/QuestionFormAnswers.xsd&quot;&amp;gt;
		&amp;lt;Answer&amp;gt;
		&amp;lt;QuestionIdentifier&amp;gt;Q1HasEvents&amp;lt;/QuestionIdentifier&amp;gt;
		&amp;lt;FreeText&amp;gt;no&amp;lt;/FreeText&amp;gt;
		&amp;lt;/Answer&amp;gt;
		&amp;lt;/QuestionFormAnswers&amp;gt;
	&lt;/Answer&gt;
&lt;/GetAssignmentResponse&gt;

答案1

得分: 6

将其翻译为中文如下:

package main

import (
	"encoding/xml"
	"fmt"
)

var data = `<?xml version="1.0"?>
<GetAssignmentResponse>
    <Answer>&lt;?xml version="1.0" encoding="UTF-8" standalone="no"?&gt;
        &lt;QuestionFormAnswers xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2005-10-01/QuestionFormAnswers.xsd"&gt;
        &lt;Answer&gt;
        &lt;QuestionIdentifier&gt;Q1HasEvents&lt;/QuestionIdentifier&gt;
        &lt;FreeText&gt;no&lt;/FreeText&gt;
        &lt;/Answer&gt;
        &lt;/QuestionFormAnswers&gt;
    </Answer>
</GetAssignmentResponse>`

type Response struct {
	XMLName xml.Name `xml:"GetAssignmentResponse"`
	Answer  string   `xml:"Answer"`
}

type Answer struct {
	XMLName  xml.Name `xml:"QuestionFormAnswers"`
	FreeText string   `xml:"FreeText"`
}

func main() {
	v := Response{}
	err := xml.Unmarshal([]byte(data), &v)
	if err != nil {
		fmt.Printf("error: %v", err)
		return
	}
	fmt.Printf("Answer = %q\n", v.Answer)
	a := Answer{}
	err = xml.Unmarshal([]byte(v.Answer), &a)
	if err != nil {
		fmt.Printf("error: %v", err)
		return
	}
	fmt.Printf("Answer = %#v\n", a)
}

你可以在playground上尝试两次解码。

英文:

Decode it twice like this (try on playground)

package main

import (
	&quot;encoding/xml&quot;
	&quot;fmt&quot;
)

var data = `&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;GetAssignmentResponse&gt;
    &lt;Answer&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&amp;gt;
        &amp;lt;QuestionFormAnswers xmlns=&quot;http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2005-10-01/QuestionFormAnswers.xsd&quot;&amp;gt;
        &amp;lt;Answer&amp;gt;
        &amp;lt;QuestionIdentifier&amp;gt;Q1HasEvents&amp;lt;/QuestionIdentifier&amp;gt;
        &amp;lt;FreeText&amp;gt;no&amp;lt;/FreeText&amp;gt;
        &amp;lt;/Answer&amp;gt;
        &amp;lt;/QuestionFormAnswers&amp;gt;
    &lt;/Answer&gt;
&lt;/GetAssignmentResponse&gt;`

type Response struct {
	XMLName xml.Name `xml:&quot;GetAssignmentResponse&quot;`
	Answer  string   `xml:&quot;Answer&quot;`
}

type Answer struct {
	XMLName  xml.Name `xml:&quot;QuestionFormAnswers&quot;`
	FreeText string   `xml:&quot;FreeText&quot;`
}

func main() {
	v := Response{}
	err := xml.Unmarshal([]byte(data), &amp;v)
	if err != nil {
		fmt.Printf(&quot;error: %v&quot;, err)
		return
	}
	fmt.Printf(&quot;Answer = %q\n&quot;, v.Answer)
	a := Answer{}
	err = xml.Unmarshal([]byte(v.Answer), &amp;a)
	if err != nil {
		fmt.Printf(&quot;error: %v&quot;, err)
		return
	}
	fmt.Printf(&quot;Answer = %#v\n&quot;, a)
}

答案2

得分: 1

作为替代方案,这个也可以工作,但不够优雅。

func (l *AssignmentAnswer) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
    var (
        content string
        resp QuestionFormAnswers
    )
    if err := d.DecodeElement(&content, &start); err != nil {
        return err
    }
    c := strings.NewReader(html.UnescapeString(content))

    dec := xml.NewDecoder(c)
    if err := dec.Decode(&resp); err != nil{
        return err
    }

    *l = AssignmentAnswer{resp}
    return nil
}

type QuestionFormAnswers struct{
    Answers []Answer `xml:"Answer"`
}

type AssignmentAnswer struct{
    QuestionFormAnswers QuestionFormAnswers
}

type Assignment struct{
    AssignmentId     string
    WorkerId         string
    HITId            string
    AssignmentStatus string
    AutoApprovalTime string
    AcceptTime       string
    SubmitTime       string
    ApprovalTime     string
    Answers          AssignmentAnswer `xml:"Answer"`
}
英文:

As an alternative, this also works, but it's not as elegant

func (l *AssignmentAnswer) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
    var (
    	content string
    	resp QuestionFormAnswers
    )
    if err := d.DecodeElement(&amp;content, &amp;start); err != nil {
        return err
    }
    c := strings.NewReader(html.UnescapeString(content))

    dec := xml.NewDecoder(c)
    if err := dec.Decode(&amp;resp); err != nil{
    	return err
    }

    *l = AssignmentAnswer{resp}
    return nil
}

type QuestionFormAnswers struct{
	Answers []Answer `xml:&quot;Answer&quot;`
}

type AssignmentAnswer struct{
	QuestionFormAnswers QuestionFormAnswers
}

type Assignment struct{
	AssignmentId     string
	WorkerId         string
	HITId            string
	AssignmentStatus string
	AutoApprovalTime string
	AcceptTime       string
	SubmitTime       string
	ApprovalTime     string
	Answers          AssignmentAnswer `xml:&quot;Answer&quot;`
}

huangapple
  • 本文由 发表于 2014年5月11日 04:22:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/23585914.html
匿名

发表评论

匿名网友

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

确定