I have 2 very similar pieces of XML retrieved from Amazon.
<?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>
I currently unmarshal this using custom types and custom unmarshal into a struct which looks like this:
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"`
}
I also have some more XML data whose structure is the same except the element 'GetLowestPricedOffersForASINResult' is called 'GetLowestPricedOffersForSKUResult'.
If I alter manually alter the tag xml:"GetLowestPricedOffersForASINResult"
to xml:"GetLowestPricedOffersForSKUResult"
then the code will happily process the other XML.
I would like to make this generic, if you like, my options seem to be:
Copy the code and have 2 large blocks which are fundamentally the same. This would be easy, but seems to me to be the wrong approach.
Bodge it by doing a search and replace on the XML raw string and simply replace GetLowestPricedOffersForSKUResult with GetLowestPricedOffersForASINResult, the code would then process the data happily, again this seems wrong.
Alter the struct tag on the fly possibly using reflection. Is this possible?
Does anyone have any suggestions for accomplishing 3 or other ideas/approaches for dealing with this in go?
Code for the GetLowestPricedOffersForASINResult result set is on the go playground (not complete but works)
Using the suggestion provided by @mkopriva I have produced an updated version of my go playground script.
I am not sure if my changes are perfect or reflect exactly what he was thinking, but for the main it seems to fulfil the main points of the problem.
If anyone has any improvements they would be welcome.