Syed
Syed

Reputation: 349

Invalid XMLDoc - There are multiple root elements. Line 9, position 2

I am calling a web service that returns an xml. When I need to have that xml in json for later use. That I can do with other methods of the web service. But when calling a specific method of web service and try to parse it, I get following error:

"There are multiple root elements. Line 9, position 2".

The xml which I receive surely has multiple root elements as it looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<Server>
   <Name>Abc</Name>
   <URL>www.abc.com</URL>
   <Env>Windows</Env>
</Server>
<Server>
   <Name>XYZ</Name>
   <URL>www.xyz.com</URL>
   <Env>Linux-Ubuntu</Env>
</Server>

So basically when I do like this:

XmlDocument doc = new XmlDocument();
doc.LoadXml(response); // response contains the xml shown above
if (doc.FirstChild.NodeType == XmlNodeType.XmlDeclaration)
        doc.RemoveChild(doc.FirstChild); // Because I want to get rid of the declaration element in the xml.

var resXML = JsonConvert.SerializeXmlNode(doc, Newtonsoft.Json.Formatting.Indented, true); // To convert xml into json

return resXML; // Finally return the json.

When debugging, it is the line doc.LoadXml(response); where it throws exception.

Please remember that this is xml I am getting from webs service, not from a file. So using XDocument doesn't work here.

Any suggestions, ideas??

Upvotes: 2

Views: 9184

Answers (2)

Syed
Syed

Reputation: 349

Well, I solved it myself. But ofcourse I got little help from another forum in getting the idea of how to do it. So the scenario was actually this:

I was getting the xml as response from a third party API (which I don't have any control over ofcourse). So I wanted to encapsulate the response in a root element called <Servers></Servers> so it becomes valid xml and then I could parse using XmlDocument or XDocument.

To fix this I used the following logic in order to encapsulate it inside a root element.

XmlReaderSettings xrs = new XmlReaderSettings();
        xrs.ConformanceLevel = ConformanceLevel.Fragment; //We confrom to the fragments because the document will not pass validation due to multiple root elements problem
        String xmlString = "<Servers>\n";
        using (XmlReader xr = XmlReader.Create(new StringReader(response), xrs))
        {
            while (xr.Read())
            {
                if (xr.NodeType != XmlNodeType.XmlDeclaration)
                {
                    switch (xr.NodeType)
                    {
                        case XmlNodeType.Element: // If nodetype is an element.
                            xmlString += "<" + xr.Name + ">";
                            break;
                        case XmlNodeType.Text: //Get text inside each element.
                            xmlString += xr.Value;
                            break;
                        case XmlNodeType.EndElement: //Close the element.
                            xmlString += "</" + xr.Name + ">";
                            break;
                    }
                }
            }
        }
        xmlString += "</Servers>"; //xmlString now has a string which is a valid xml. So XDocument or XmlDocument parse will not fail over it.

        var doc = XDocument.Parse(xmlString);
        var json = JsonConvert.SerializeXNode(doc,Newtonsoft.Json.Formatting.Indented, true);
        return json; // I convert it to json so the client can consume it.

Done!

Ofcourse it is a work around but as the API guyes will take time before they will fix the invalid xml, so I had to go this way till then.

Upvotes: 2

Jacob Berg
Jacob Berg

Reputation: 1

In the xml there should be a <Servers> tag where you put the <Server> elements.

<?xml version="1.0" encoding="UTF-8"?>
<Servers>
<Server>
   <Name>Abc</Name>
   <URL>www.abc.com</URL>
   <Env>Windows</Env>
</Server>
<Server>
   <Name>XYZ</Name>
   <URL>www.xyz.com</URL>
   <Env>Linux-Ubuntu</Env>
</Server>
</Servers>

Upvotes: 0

Related Questions