Issue parsing XML string to xDocument

3.7k views Asked by At

I am receiving an XML string from the controller of my web API that is constructed as shown:

private string CreateXDoc(IEnumerable<PassedJSONConverted> passed)
    {
        XNamespace xmlns = "http://host.adp.com";

        var doc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"));

        var jobListElement = new XElement(xmlns + "JobXML");

        foreach (var objectItem in passed)
        {
            var loopElement = new XElement(xmlns + "JobsXML", new XElement(xmlns + "ID", objectItem.ID.ToString()), new XElement(xmlns + "Name", objectItem.Name), new XElement(xmlns + "Age", objectItem.Age.ToString()), new XElement(xmlns + "JobTitle", objectItem.JobTitle), new XElement(xmlns + "StartDate", objectItem.StartDate));

            jobListElement.Add(loopElement);
        }

        doc.Add(jobListElement);

        //Format without \n's
        return doc.ToString(SaveOptions.DisableFormatting);
    }

This is fine and the XML is set as shown:

- <JobXML xmlns="http://host.xxx.com">
 - <JobsXML>
    <ID>1</ID> 
    <Name>Dave</Name> 
    <Age>23</Age> 
    <JobTitle>Developer</JobTitle> 
    <StartDate>10/24/2013 6:40:28 AM</StartDate> 
  </JobsXML>
- <JobsXML>
    <ID>2</ID> 
    <Name>John</Name> 
    <Age>44</Age> 
    <JobTitle>QA</JobTitle> 
    <StartDate>10/24/2013 6:40:28 AM</StartDate> 
  </JobsXML>
- <JobsXML>
    <ID>3</ID> 
    <Name>Dave</Name> 
    <Age>23</Age> 
    <JobTitle>Senior Developer</JobTitle> 
    <StartDate>10/24/2013 6:40:28 AM</StartDate> 
  </JobsXML>
 </JobXML>

When I then return this as a string and try to parse it back to an xDoc as shown:

private static string HandleResponse(HttpWebResponse httpResponse)
    {
        using (var responseReader = new StreamReader(httpResponse.GetResponseStream(), Encoding.UTF8))

        {
            string responsePayload = responseReader.ReadToEnd();

            var newxDoc = XDocument.Parse(responsePayload);

            return responsePayload;
        }
    }

The string 'responsePayLoad' at runtime is set as shown:

 "<JobXML xmlns=\"http://host.adp.com\"><JobsXML><ID>1</ID><Name>Dave</Name><Age>23</Age><JobTitle>Developer</JobTitle><StartDate>10/24/2013 6:45:22 AM</StartDate></JobsXML><JobsXML><ID>2</ID><Name>John</Name><Age>44</Age><JobTitle>QA</JobTitle><StartDate>10/24/2013 6:45:22 AM</StartDate></JobsXML><JobsXML><ID>3</ID><Name>Dave</Name><Age>23</Age><JobTitle>Senior Developer</JobTitle><StartDate>10/24/2013 6:45:22 AM</StartDate></JobsXML></JobXML>"

This is giving me an exception at the 'newxDoc' object of:

XmlException is unhandled. Data at the root level is invalid. Line 1, position 1.

Can anyone tell me where I'm going wrong?

4

There are 4 answers

0
Ben Smith On BEST ANSWER

The problem is that your responsePayLoad string is not valid XML.

Your problem is here:

"<JobXML xmlns=\"http://host.adp.com\">

The presence of the quote character at the start and end of the string, and the backslashes before the quotes, is causing the XML to be malformed. If your string did not have these quotes at the start and end and the backslashes the XML will be valid i.e. This will make the XML well-formed:

<JobXML xmlns="http://host.adp.com">...<\JobXML>

As for why this problem is occurring, it could be because of the way that you are creating your XDocument. The example in Microsoft's documentation here, indicates that an XDocument which uses a specific XDeclaration should be instantiated using the following constructor:

XDocument(XDeclaration, Object[])

So I'd try re-factoring your code to make us of this method e.g.

private string CreateXDoc(IEnumerable<PassedJSONConverted> passed)
{
    XNamespace xmlns = "http://host.adp.com";

    var xdec = new XDeclaration("1.0", "utf-8", "yes");

    var jobListElement = new XElement(xmlns + "JobXML");

    foreach (var objectItem in passed)
    {
        var jobXml = new XElement(xmlns + "JobsXML", 
                            new XElement(xmlns + "ID", objectItem.ID.ToString()), 
                            new XElement(xmlns + "Name", objectItem.Name), 
                            new XElement(xmlns + "Age", objectItem.Age.ToString()), 
                            new XElement(xmlns + "JobTitle", objectItem.JobTitle), 
                            new XElement(xmlns + "StartDate", objectItem.StartDate));

        jobListElement.Add(jobXml);
    }

    var doc = new XDocument(
        xdec,
        new XElement(jobListElement)
    );

    //Format without new lines
    return doc.ToString(SaveOptions.DisableFormatting);
}

If this does not work also try turning off the disable formating in CreateXDoc i.e.

return doc.ToString();
0
ubergeekCD On

Try adding <?xml version="1.0" encoding="UTF-8" ?> to the beginning of your XML String.

Don't worry about the escaped quotes, they are there because you XML is wrapped in a string.

0
Esam Naas On

the above two answers combined will sort it out

When I repeated the xml script I got this error

XML Parsing Error: not well-formed Location: Untitled-1.xml Line Number 2, Column 15: http://host.adp.com\">1Dave23 --------------^ Developer10/24/2013 6:45:22 AM2John44QA10/24/2013 6:45:22 AM3Dave23Senior Developer10/24/2013 6:45:22 AM

this is the correct form

<?xml version="1.0" encoding="utf-8"?>
<JobXML xmlns="http://host.adp.com\"><JobsXML><ID>1</ID><Name>Dave</Name><Age>23</Age><JobTitle>Developer</JobTitle><StartDate>10/24/2013 6:45:22 AM</StartDate></JobsXML><JobsXML><ID>2</ID><Name>John</Name><Age>44</Age><JobTitle>QA</JobTitle><StartDate>10/24/2013 6:45:22 AM</StartDate></JobsXML><JobsXML><ID>3</ID><Name>Dave</Name><Age>23</Age><JobTitle>Senior Developer</JobTitle><StartDate>10/24/2013 6:45:22 AM</StartDate></JobsXML></JobXML>
0
Ahmad Hindash On

as you asked , parsing XML string to xdocument :

simply try this code

 XDocument document = XDocument.Parse(xml);

but I have a concern if this good for huge xml string such as an xml with more than one hunderd thousand line of codes. I've tried this method for an xml document with 10000 line of code and it took 1.5 second