简体   繁体   中英

How do I use c# XMLSerializer to create an XML request that can allow multple child elements with the same name but not as an array

I am working with the USPS Tracking API. The have a specification for a request as I have listed below;

<TrackFieldRequest PASSWORD="" USERID="prodsolclient" APPID="">
    <Revision>1</Revision>
    <ClientIp>111.0.0.1</ClientIp>
    <TrackID ID="5551212699300000962610" />
</TrackFieldRequest>

And they state in their user manual that "Up to 10 tracking IDs may be contained in each request input to the Web Tool server."

I interpret this as meaning that the TrackFieldRequest can have up to 10 of the TrackID child elements. However, these multiple TrackID elements are not defined as being in an array. They are just up to 10 consecutive TrackID child elements of the TrackFieldRequest element.

So, I am not sure how to build up the CLR object to pass to the XMLSerializer if I want to include 10 of the TrackID child elements.

I tried creating a TrackFieldRequest class that has a property that is a "List TrackIds" but the USPS website gives me an error response saying "The element 'TrackFieldRequest' has invalid child element 'TrackIds'. List of possible elements expected: 'TrackID'"

How do I model the CLR class so that the XMLSerializer can use it to generate up to 10 TrackID child elements, without using a List or Array property in my TrackFieldRequest class?

Here is my current TrackFieldRequest class

public class TrackFieldRequest
{
    // Based upon USPS Web Tools API User Guide(Track & Confirm API) version 3.3 dated 2/28/16
    // at https://www.usps.com/business/web-tools-apis/track-and-confirm-api.pdf

    [XmlAttribute("USERID")]
    public string UserId { get; set; }

    [XmlElement("Revision")]
    public int Revision { get; set; }

    [XmlElement("ClientIp")]
    public string ClientIp { get; set; }

    [XmlElement("SourceIdZIP")]
    public string SourceIdZip { get; set; }

    public List<TrackId> TrackIds { get; set; }
}

Here is my current TrackID class

public class TrackId
{
    // Based upon USPS Web Tools API User Guide(Track & Confirm API) version 3.3 dated 2/28/16
    // at https://www.usps.com/business/web-tools-apis/track-and-confirm-api.pdf

    public TrackId(string a_Id, string a_destinationZipCode, string a_mailingDate)
    {
        ID = a_Id;
        DestinationZipCode = a_destinationZipCode;
        MailingDate = a_mailingDate.ToString();
    }

    // Parameterless constructor is needed for the XMLSerializer
    public TrackId()
    {

    }

    [XmlAttribute]
    public string ID { get; set; }

    [XmlElement("DestinationZipCode")]
    public string DestinationZipCode { get; set; }

    [XmlElement("MailingDate")]
    public string MailingDate { get; set; }

}

Here is my methods to convert the the CLR class into Xml using an XmlWriter

    private string ConvertTrackingRequestToXml(TrackFieldRequest a_trackingRequest)
    {
        try
        {
            var xmlWriterSettings = new XmlWriterSettings
            {
                Encoding = new UTF8Encoding(false),
                Indent = true,
                IndentChars = "\t"
            };
            XmlSerializer xmlSerializer = new XmlSerializer(a_trackingRequest.GetType());
            using (StringWriter stringWriter = new StringWriter())
            using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter, xmlWriterSettings))
            {
                xmlSerializer.Serialize(xmlWriter, a_trackingRequest);
                return stringWriter.ToString();
            }
        }
        catch (Exception ex)
        {
            Logger.LogError("Could not convert tracking request into Xml.", ex);
            return null; 
        }
    }

I would prefer not to use the XmlSerializer rather than manually building up the request XML string from a string builder, if possible.

Any ideas?

Thanks in advance for any help you can provide.

Try this

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] trackingNumbers = {"5551212699300000962610", "5551212699300000962611", "5551212699300000962612"};
            XElement trackFieldRequest = new XElement("TrackFieldRequest", new object[] {
                new XAttribute("PASSWORD", "password"),
                new XAttribute("USERID", "prodsolclient"),
                new XAttribute("APPID", ""),
                new XElement("Revision",1),
                new XElement("ClientIp", "111.0.0.1")
            });

            foreach (string trackingNumber in trackingNumbers)
            {
                trackFieldRequest.Add(new XElement("TrackID", trackingNumber));
            }

            string xml = trackFieldRequest.ToString();
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM