如何在Go中更改struct XML标签?

时间:2018-11-08 09:24:30

标签: xml go

我从亚马逊检索了2个非常相似的XML。

<?xml version="1.0"?><GetLowestPricedOffersForASINResponse xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01">
<GetLowestPricedOffersForASINResult MarketplaceID="A1F83G8C2ARO7P" ItemCondition="New" ASIN="0195019199" status="Success">
    <Identifier>
        <MarketplaceId>A1F83G8C2ARO7P</MarketplaceId>
        <ASIN>0195019199</ASIN>
        <ItemCondition>New</ItemCondition>
        <TimeOfOfferChange>2018-11-07T02:05:14.342Z</TimeOfOfferChange>
    </Identifier>
    <Summary>
        <TotalOfferCount>45</TotalOfferCount>
        <NumberOfOffers>
            <OfferCount condition="used" fulfillmentChannel="Merchant">14</OfferCount>
            <OfferCount condition="new" fulfillmentChannel="Amazon">1</OfferCount>
            <OfferCount condition="new" fulfillmentChannel="Merchant">30</OfferCount>
        </NumberOfOff........ etc xml continues

</GetLowestPricedOffersForASINResult>
<ResponseMetadata>
    <RequestId>fef8c86d-c563-4373-81c9-78dcf691283c</RequestId>
</ResponseMetadata>
</GetLowestPricedOffersForASINResponse>

我目前使用自定义类型将其解组,然后将自定义解组为如下所示的结构:

type LowestPricedPricedOffers struct {

Error AmazonError `xml:"Error"`
All   struct {

        /*The only way I found to retrieve 'status' from the GetLowestPricedOffersForASINResult element was to wrap in the struct 'All'.
        This is the only reason the All struct exists.  Ideally would like to remove*/
        Status            string     `xml:"status,attr"` 

    ASIN              string     `xml:"Identifier>ASIN"`
    ItemCondition     string     `xml:"Identifier>ItemCondition"`
    TimeOfOfferChange string     `xml:"Identifier>TimeOfOfferChange"`
    TotalOfferCount   int        `xml:"Summary>TotalOfferCount"`
    ListPrice         float32    `xml:"Summary>ListPrice>Amount"`
    OfferCount        offerCount `xml:"Summary>NumberOfOffers"`

    //Want to take Currency code from LowestPrices below but cannot think of a way to achieve this against the lowestPrices type
    //CurrencyCode         string               `xml:"CurrencyCode"` 

    BuyBoxPrices         buyBoxPrices         `xml:"Summary>BuyBoxPrices"`
    LowestPrices         lowestPrices         `xml:"Summary>LowestPrices"`
    BuyBoxEligibleOffers buyBoxEligibleOffers `xml:"Summary>BuyBoxEligibleOffers"`

    Offers []struct {
        SubCondition                 string  `xml:"SubCondition"`
        SellerPositiveFeedbackRating float32 `xml:"SellerFeedbackRating>SellerPositiveFeedbackRating"`
        FeedbackCount                int     `xml:"SellerFeedbackRating>FeedbackCount"`
        ShippingTime                 struct {
            MinimumHours     int    `xml:"minimumHours,attr"`
            MaximumHours     int    `xml:"maximumHours,attr"`
            AvailabilityType string `xml:"availabilityType,attr"`
        }
        ListingPrice        float32 `xml:"ListingPrice>Amount"`
        Shipping            float32 `xml:"Shipping>Amount"`
        ShipsFrom           string  `xml:"ShipsFrom>Country"`
        IsFulfilledByAmazon bool    `xml:"IsFulfilledByAmazon"`
        IsBuyBoxWinner      bool    `xml:"IsBuyBoxWinner"`
        IsFeaturedMerchant  bool    `xml:"IsFeaturedMerchant"` //true if the seller of the item is eligible to win the Buy Box.
    } `xml:"Offers>Offer"`
} `xml:"GetLowestPricedOffersForASINResult"`

}

除了元素'GetLowestPricedOffersForASINResult'被称为'GetLowestPricedOffersForSKUResult'之外,我还拥有其他一些结构相同的XML数据。

如果我手动将标签xml:"GetLowestPricedOffersForASINResult"更改为xml:"GetLowestPricedOffersForSKUResult",则代码将愉快地处理其他XML。

如果您愿意,我想将此通用名设为:

  1. 复制代码,并具有2个大体上相同的大块。这很容易,但是在我看来似乎是错误的方法。

  2. 通过搜索并替换XML原始字符串将其结合起来,并简单地将GetLowestPricedOffersForSKUResult替换为GetLowestPricedOffersForASINResult,然后代码将愉快地处理数据,这似乎又是错误的。

  3. 动态更改struct标签,可能使用反射。这可能吗?

有人对完成3个或其他想法/方法有什么建议吗?

GetLowestPricedOffersForASINResult结果集的代码在go playground上(不完整,但是可以使用)

1 个答案:

答案 0 :(得分:0)

使用@mkopriva提供的建议,我制作了go playground脚本的更新版本。

我不确定我所做的更改是否完美无缺或是否完全反映了他的想法,但从总体上看,这似乎可以解决问题的要点。

如果任何人有任何改进,都将受到欢迎。