Reputation: 349
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
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
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