英文:
XML unmarshalling in Golang
问题
我想将以下 XML 负载解组为结构体:
<linearPackagePublish>
<linearPackage>
<name>ABC</name>
<packagedServiceReference>
<availabilityWindowEnd>2329-12-31 23:59:59</availabilityWindowEnd>
<availabilityWindowStart>2007-11-14 11:40:00</availabilityWindowStart>
<packagedServiceId>1111111111</packagedServiceId>
</packagedServiceReference>
<partnerPackageId>XXXXXXX</partnerPackageId>
</linearPackage>
<partnerId>XXXXXX</partnerId>
<wantLinearPublishResult>true</wantLinearPublishResult>
</linearPackagePublish>
我想在 <wantLinearPublishResult>
标签之前添加 transactionId
,如下所示:
<linearPackagePublish>
<linearPackage>
<name>ABC</name>
<packagedServiceReference>
<availabilityWindowEnd>2329-12-31 23:59:59</availabilityWindowEnd>
<availabilityWindowStart>2007-11-14 11:40:00</availabilityWindowStart>
<packagedServiceId>1111111111</packagedServiceId>
</packagedServiceReference>
<partnerPackageId>XXXXXXX</partnerPackageId>
</linearPackage>
<partnerId>XXXXXX</partnerId>
<transactionId>111111111111</transactionId>
<wantLinearPublishResult>true</wantLinearPublishResult>
</linearPackagePublish>
为此,我尝试将上述 XML 解组为以下结构体:
type linearPackagePublish struct {
LinearPackage string `xml:"linearPackage"`
MsoPartnerID string `xml:"partnerId"`
TransactionID string `xml:"transactionId,omitempty"`
WantLinearPublishResult bool `xml:"wantLinearPublishResult,omitempty"`
}
但问题是,我不想解组 linearPackage
元素,所以我在结构体中将 LinearPackage
设置为字符串。
我也可以使用正则表达式来实现,但如果 XML 发生变化,这种方法会更容易出错。
有没有办法将某些嵌套的 XML 元素作为字符串处理?
英文:
I want to unmarshall the below xml payload to struct
<linearPackagePublish>
<linearPackage>
<name>ABC</name>
<packagedServiceReference>
<availabilityWindowEnd>2329-12-31 23:59:59</availabilityWindowEnd>
<availabilityWindowStart>2007-11-14 11:40:00</availabilityWindowStart>
<packagedServiceId>1111111111</packagedServiceId>
</packagedServiceReference>
<partnerPackageId>XXXXXXX</partnerPackageId>
</linearPackage>
<partnerId>XXXXXX</partnerId>
<wantLinearPublishResult>true</wantLinearPublishResult>
</linearPackagePublish>
I want to add transactionId just before <wantLinearPublishResult> tag like this:
<linearPackagePublish>
<linearPackage>
<name>ABC</name>
<packagedServiceReference>
<availabilityWindowEnd>2329-12-31 23:59:59</availabilityWindowEnd>
<availabilityWindowStart>2007-11-14 11:40:00</availabilityWindowStart>
<packagedServiceId>1111111111</packagedServiceId>
</packagedServiceReference>
<partnerPackageId>XXXXXXX</partnerPackageId>
</linearPackage>
<partnerId>XXXXXX</partnerId>
<transactionId>111111111111</transactionId>
<wantLinearPublishResult>true</wantLinearPublishResult>
</linearPackagePublish>
For this purpose I was trying to unmarshall the above xml to below struct:
type linearPackagePublish struct {
LinearPackage string `xml:"linearPackage"`
MsoPartnerID string `xml:"partnerId"`
TransactionID string `xml:"transactionId,omitempty"`
WantLinearPublishResult bool `xml:"wantLinearPublishResult,omitempty"`
}
But the thing is I don’t want to unmarshall the linearPackage element that is why I put LinearPackage as string in struct
I can also do it via regex but it will be more error prone if something change in the xml.
Is there any way that we can make some nested xml element as a string??
答案1
得分: 1
你可以定义一个自定义类型,其中包含自己定义的marshal和unmarshal函数,而不是尝试使用字符串。这样你就可以直接控制该元素。
你可以看到自定义数据类型包含一个xml.Tokens数组。这个数组在解组过程中被填充,然后在编组过程中写入编码器。
type skipUnmarshal struct {
data []xml.Token
}
func (s skipUnmarshal) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
for i := 0; i < len(s.data); i++ {
e.EncodeToken(s.data[i])
}
return nil
}
func (s *skipUnmarshal) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
for {
t, err := d.Token()
if err != nil {
break // or alternatively return the error
}
s.data = append(s.data, t)
}
return nil
}
你可以在Go Playground上看到一个工作示例。
英文:
Edited to provide more detail. Including a working demo on Go Playground
Rather than trying to use a string you can define a custom type, with its own marshal and unmarshal functions defined. That way you can have direct control over that element.
You can see the custom datatype holds an array of xml.Tokens. This array is populated during unmarshalling and then written to the encoder during marshalling.
type skipUnmarshal struct {
data []xml.Token
}
func (s skipUnmarshal) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
for i := 0; i < len(s.data); i++ {
e.EncodeToken(s.data[i])
}
return nil
}
func (s *skipUnmarshal) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
for {
t, err := d.Token()
if err != nil {
break // or alternatively return the error
}
s.data = append(s.data, t)
}
return nil
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论