locked
Multiple nodes for XML RRS feed

  • Question

  • User-501297529 posted

    This is for Amazon Web ServicesI am trying get c# to select multiple nodes in XML. I'm not sure how to do this here is the xml code followed by c# and am not sure if I have the code set up correctly:

    <PackageTrackingInfo> <TrackingNumber>123456789</TrackingNumber> <PackageDestinationLocation> <City>Seattle</City> <StateProvince>WA</StateProvince> <PostalCode>98107</PostalCode> <CountryCode>US</CountryCode> </PackageDestinationLocation> <PackageDeliveryDate> <ScheduledDeliveryDate>2004-09-15</ScheduledDeliveryDate>
    </PackageTrackingInfo> 

     

    And here is c# code:

     public string ProcessXML(string xmlRequest)
            {
                XmlDocument rsp = null;
                Saia.Presentation.Website.SaiaSecure.WebService.Shipment.Response response = new Saia.Presentation.Website.SaiaSecure.WebService.Shipment.Response();
                string testMode = "";
    
                try
                {
                    if (bool.Parse(WebConfigurationManager.AppSettings["Debug"]) == true)
                        File.WriteAllText("c:\\temp\\" + DateTime.Now.ToString("MMddyyy_HHmmss") + ".xml", xmlRequest);
                    // Determine Method to Call
                    XmlDocument doc = new XmlDocument();
                    doc.XmlResolver = null;
                    doc.LoadXml(xmlRequest);
    
                    string method = doc.FirstChild.Name;
    
                    if (method.ToLower() == "xml")
                    {
                        method = doc.FirstChild.NextSibling.Name;
                    }
    
                    if (method == "AmazonTrackingRequest")
                    {
                        Saia.Data.General.Shipment prc = new Data.General.Shipment();
                        string pronum = doc.FirstChild.SelectSingleNode("TrackingNumber").InnerText;
                        prc.GetByProNumber(decimal.Parse(pronum));
                        var city = doc.SelectNodes("City");
                        var state = doc.SelectNodes("State");
                        var postcode = doc.SelectSingleNode("PostalCode");
                        //string city = doc.SelectNodes("City");
                        //string state = doc.SelectNodes("State").ToString();
                        //string postcode = doc.SelectSingleNode("PostalCode").InnerText;
                        //string country = doc.SelectSingleNode("CountryCode").InnerText;
    
    
    
    
    
                        rsp = new XmlDocument();
    
                    }
    
                }
                catch (CodeException e)
                {
    
    
                    Core.Framework.Debug.CodeException(xmlRequest, e);
                }
                catch (Exception e)
                {
    
                    Core.Framework.Debug.Exception(xmlRequest, e);
                }
    
                return rsp.InnerXml;
            }
        }
    }

    I'm just not sure if I'm on the correct path with what I have and need some assistance.

    Basically what I'm trying to do is this: There are two pieces of code I provided: XML and C#. In the if (method == "AmazonTrackingRequest") statement in the C# code, I have a SelectSingleNode for Tracking Number and if you look at the XML code Tracking Number is the first field. I'm not sure how to code the next field in that XML which is City in C# like I did for the Tracking Number field and then so on with the next field State, and then Postal Code... Does that make sense? For example, the code that I have in C# for City:
    var city = doc.SelectNodes("City");, I'm not sure if that is correct and that is what I need assistance with. 

    Tuesday, September 12, 2017 9:02 PM

Answers

All replies

  • User-707554951 posted

    Hi bootzilla,

    From your description, you would track number field and then so on with the next field state.

    You could refer to the following code to get the data in XML:

    string xml = @"<PackageTrackingInfo><TrackingNumber>123456789</TrackingNumber><PackageDestinationLocation>
                        <City>Seattle</City><StateProvince>WA</StateProvince><PostalCode>98107</PostalCode><CountryCode>US</CountryCode>
                        </PackageDestinationLocation><PackageDeliveryDate><ScheduledDeliveryDate>2004-09-15</ScheduledDeliveryDate></PackageDeliveryDate></PackageTrackingInfo>";
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(xml);
               
                var a = doc.SelectSingleNode("descendant::TrackingNumber").InnerText;
                var b = doc.SelectSingleNode("descendant::City").InnerText;
                var c = doc.SelectSingleNode("descendant::StateProvince").InnerText;
                var d = doc.SelectSingleNode("descendant::PostalCode").InnerText;
                var f = doc.SelectSingleNode("descendant::CountryCode").InnerText;
                var g = doc.SelectSingleNode("descendant::ScheduledDeliveryDate").InnerText;
                Label1.Text = a.ToString();
                Label2.Text = b.ToString();
                Label3.Text = c.ToString();
                Label4.Text = d.ToString();
                Label5.Text = f.ToString();
                Label6.Text = g.ToString();
    

    Output:

    For the usage of SelectSingleNode Method. please refer to the following link:

    https://msdn.microsoft.com/en-us/library/system.xml.xmlnode.selectsinglenode(v=vs.110).aspx

    Best regards

    Cathy

    Wednesday, September 13, 2017 9:03 AM
  • User-501297529 posted

    Hi Cathy,

    So do I have to use labels? Doesn't that require to use those on the front end? If so can I hide them?

    I created an xml document/schema that will export as the xml structure, how do I send that out as a string? 

    Wednesday, September 13, 2017 1:23 PM
  • User-707554951 posted

    Hi bootzilla,

    The reason for using label is that I could display the data of each single node in xml document on page.

    So, It isn't required for you to use label. you could remove related code directly instead of hiding them.

    You could refer to the code as below:

    string a = doc.SelectSingleNode("descendant::TrackingNumber").InnerText;
                string b = doc.SelectSingleNode("descendant::City").InnerText;
                string c = doc.SelectSingleNode("descendant::StateProvince").InnerText;
                string d = doc.SelectSingleNode("descendant::PostalCode").InnerText;
                string f = doc.SelectSingleNode("descendant::CountryCode").InnerText;
                string g = doc.SelectSingleNode("descendant::ScheduledDeliveryDate").InnerText;

    I created an xml document/schema that will export as the xml structure, how do I send that out as a string? 

    I don't understand your idea clearly about this:

    If you still have problem, would you please feel free to tell me and show more detail about your problem.

    Best regards

    Cathy

    Thursday, September 14, 2017 6:08 AM
  • User-501297529 posted

    Hi Cathy,

    Well I tried something a little different to get the XML. What I'm trying to do is output the XML, so I formatted using XElement which is associated with LINQ i believe. It looks like this and this is not all of the code but some it so you get the idea:

     public string ProcessXML(string xmlRequest)
            {
                XDocument rspxml = null;
                Saia.Presentation.Website.SaiaSecure.WebService.Shipment.Response response = new Saia.Presentation.Website.SaiaSecure.WebService.Shipment.Response();
                string testMode = "";
    
                try
                {
                    if (bool.Parse(WebConfigurationManager.AppSettings["Debug"]) == true)
                        File.WriteAllText("c:\\temp\\" + DateTime.Now.ToString("MMddyyy_HHmmss") + ".xml", xmlRequest);
                    // Determine Method to Call
                    XmlDocument doc = new XmlDocument();
                    doc.XmlResolver = null;
                    doc.LoadXml(xmlRequest);
                   
                    string method = doc.FirstChild.Name;
    
                    if (method.ToLower() == "xml")
                    {
                        method = doc.FirstChild.NextSibling.Name;
                    }
    
                    if (method == "AmazonTrackingRequest")
                    {
                        Saia.Data.General.Shipment prc = new Data.General.Shipment();
                        string pronum = doc.FirstChild.SelectSingleNode("TrackingNumber").InnerText;
                        prc.GetByProNumber(decimal.Parse(pronum));
    
    
    
                        rspxml = XDocument.Load("<?xml version=\"1.0\" encoding=\"UTF-8\"?><AmazonTrackingResponse xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"AmazonTrackingResponse.xsd\">");
                        rspxml.Root.Add(new XElement("APIVersion", "4.0"));
                        rspxml.Root.Add(new XElement("PackageTrackingInfo"));
                        rspxml.Root.Element("PackageTrackingInfo").Add(new XElement("TrackingNumber", prc.ProNumber.ToString()));
                        rspxml.Root.Add(new XElement("PackageDestinationLocation"));
                        rspxml.Root.Element("PackageDestinationLocation").Add(new XElement("City", prc.Consignee.ToString()));
                        rspxml.Root.Element("PackageDestinationLocation").Add(new XElement("StateProvince", prc.Consignee.ToString()));
                        rspxml.Root.Element("PackageDestinationLocation").Add(new XElement("PostalCode", prc.Consignee.ToString()));
                        rspxml.Root.Element("PackageDestinationLocation").Add(new XElement("CountryCode", prc.Consignee.ToString()));
                        rspxml.Root.Add(new XElement("PackageDeliveryDate"));
                        rspxml.Root.Element("PackageDeliveryDate").Add(new XElement("ScheduledDeliveryDate", prc.Consignee.ToString()));
                        rspxml.Root.Element("PackageDeliveryDate").Add(new XElement("ReScheduledDeliveryDate", prc.Consignee.ToString()));
                       .....
    
                    }
    
                }
                catch (CodeException e)
                {
    
    
                    Core.Framework.Debug.CodeException(xmlRequest, e);
                }
                catch (Exception e)
                {
    
                    Core.Framework.Debug.Exception(xmlRequest, e);
                }
    
                return rspxml.ToString();
            }

    The problem I'm having now is when I debug by stepping into the code it blows up with an 'object is not set to instance of an object' error in the class file on this line:

    string response = shipment.ProcessXML(xmlreq);

    class Class1
    	{
    		/// <summary>
    		/// The main entry point for the application.
    		/// </summary>
    		[STAThread]
    		static void Main(string[] args)
    		{
    			try
    			{
                    string flg = string.Empty;
                    while (flg != "q")
                    {
    
                        System.Text.StringBuilder request = new System.Text.StringBuilder();
                        saia.shipment.Shipment shipment = new saia.shipment.Shipment();
                        shipment.Timeout = 120000;
                        request.Append("<GetByProNumber>");
                        request.Append("<UserID>chrltl</UserID>");
                        request.Append("<Password>chrltl14800</Password>");
                        request.Append("<TestMode>N</TestMode>");
                        request.Append("<ProNumber>983579110</ProNumber>");
                        request.Append("</GetByProNumber>");
    
                        
                        string xmlreq = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><AmazonTrackingRequest xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"AmazonTrackingRequest.xsd\"><Validation><UserID>AMZN</UserID><Password>12345</Password></Validation><APIVersion>4.0</APIVersion><TrackingNumber>10143826470</TrackingNumber></AmazonTrackingRequest>";
                        
    
                        string response = shipment.ProcessXML(xmlreq);
                        System.Xml.XmlDocument xmlResponse = new System.Xml.XmlDocument();
                        xmlResponse.LoadXml(response);
    
                        // Note: These examples use SelectSingleNode() which accepts a string 
                        // containing a XPath expression. This is a common way to retrieve a node 
                        // from a small XML Document. 
    
                        if (xmlResponse.SelectSingleNode("/Response/Code").InnerText != "")
                        {
                            // Add error handling code in case Saia responds 
                            // with an Error Code
    
                            System.Console.WriteLine(xmlResponse.SelectSingleNode("/Response/Code").InnerText);
                            System.Console.WriteLine(xmlResponse.SelectSingleNode("/Response/Element").InnerText);
                            System.Console.WriteLine(xmlResponse.SelectSingleNode("/Response/Fault").InnerText);
                            System.Console.WriteLine(xmlResponse.SelectSingleNode("/Response/Message").InnerText);
                        }
                        else
                        {
                            //System.Console.WriteLine(xmlResponse.SelectSingleNode("/Response/CurrentStatus").InnerText);
                            System.Console.WriteLine(xmlResponse.SelectSingleNode("/Response/Consignee/Name").InnerText);
                            System.Console.WriteLine(xmlResponse.SelectSingleNode("/Response/Consignee/AccountNumber").InnerText);
                            System.Console.WriteLine(xmlResponse.SelectSingleNode("/Response/Consignee/Address1").InnerText);
                            .....
                        }
                        shipment.Dispose();
                        request = null;
                    }
    			}
    			catch (System.Exception ex)
    			{
                    Console.WriteLine(ex.ToString());
                    Console.ReadLine();
    			}
    		}
    	}

    It seems like it's something wrong with getting into the ProcessXML method but I'm not sure what it could be.

    Again I'm trying to build out the “rspxml” document to generate the output xml.

    Thursday, September 14, 2017 7:21 PM
  • User-707554951 posted

    Hi bootzilla,

    The exception is a null reference exception. You're trying to access an instance member on a variable that is null.

    The problem may like this:

    if (xmlResponse.SelectSingleNode("/Response/Code").InnerText != "")

    The SelectSingleNode method finds the first node that matches the XPath you give it. This can return null. Setting a breakpoint on this line will likely reveal that it is, in fact, null. So the XPath isn't finding an element. You should always check for null when calling this method anyway so you'll want to adjust this line (and all the other places you call it) to handle the case where the element doesn't exist.

    For more detail, you could refer to the following links:

    https://social.msdn.microsoft.com/Forums/en-US/3f7c1d0a-2667-4023-908e-731c358bf53c/error-on-xmlresponse?forum=csharpgeneral

    https://stackoverflow.com/questions/10185115/c-sharp-xml-object-reference-not-set-to-an-instance-of-an-object

    https://stackoverflow.com/questions/4338387/xml-document-object-reference-not-set-to-an-instance-of-an-object

    Besides, I suggest you could set break point in ProcessXML() method to see which code line arise the error.

    Then you could show me specified code line.

    Best regards

    Cathy

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, September 15, 2017 8:46 AM
  • User-501297529 posted

    Hi Cathy

    I updated this

    if (xmlResponse.SelectSingleNode("/Response/Code").InnerText != "")

    to this:

    var code = xmlResponse.SelectSingleNode("/Response/Code");
     if (code == null)

    and now I get 'Client found response content type of 'text/html; charset=utf-8', but expected 'text/xml' error.

    I did some research on this error and this is caused because the consumer is expect xml from the webservice but the webservice returns HTML. It also could be a configuration error in web.config. Checking the connection string etc might be the answer for the time out.

    Friday, September 15, 2017 2:06 PM
  • User-501297529 posted

    Need help on my last issue from someone please.

    Monday, September 18, 2017 1:08 PM
  • User-707554951 posted

    Hi bootzilla,

    I think the problem lies in web.config file.

    Try to do the following:

    1. open the web.config file and check the first line <?xml version="1.0" .... ?>. no spaces are allowed before the start of the line.

    2. the fault lie in the timeout value in the web server

    <maxRequestLength>-1</maxRequestLength>
    <executionTimeout value="-1" />
    <httpRuntime maxRequestLength="102400" executionTimeout="2700"/> 

    3.If you are using .NET version 4.0. the validateRequestion is turned on by default for all the pages. You can turn the default validation off.

    In the web.config add the following lines for system.web
                  

     <httpRuntime requestValidationMode="2.0" />

    and       

    <pages validateRequest="false" />

      4.Locate Web References - this will be visible only if you have added a web service reference in your project.Right click and click update web reference.

    Best regards

    Cathy

    Tuesday, September 19, 2017 5:56 AM