Converting JSON to XML - c#

I trying to convert JSON output into XML. Unfortunately I get this error:
JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifing a DeserializeRootElementName.
This is what I up to now created.
string url = string.Format("https://graph.facebook.com/{0}?fields=posts.fields(message)&access_token={1}", user_name, access_token);
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
jsonOutput = reader.ReadToEnd();
Console.WriteLine("THIS IS JSON OUTPUT: " + jsonOutput);
}
XmlDocument doc = (XmlDocument)JsonConvert.DeserializeXmlNode(jsonOutput);
Console.WriteLine(doc);
And this is my JSON output:
{"id":"108013515952807","posts":{"data":[{"id":"108013515952807_470186843068804","created_time":"2013-05-14T20:43:28+0000"},{"message":"TEKST","id":"108013515952807_470178529736302","created_time":"2013-05-14T20:22:07+0000"}
How can I solve this problem?

Despite the fact your JSON provided in the question is not complete, you have multiple properties at the top level as indicated by the exception. You have to define the root for it to get valid XML:
var doc = JsonConvert.DeserializeXmlNode(jsonOutput, "root");
EDIT: In order to print out your XML with indentation you can use XDocument class from System.Xml.Linq namespace: XDocument.Parse(doc.InnerXml).

I thought it's worth linking to the Documentation for turning xml to json and the other way around.
The guys are right..
// To convert an XML node contained in string xml into a JSON string
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string jsonText = JsonConvert.SerializeXmlNode(doc);
// To convert JSON text contained in string json into an XML node
XmlDocument doc = (XmlDocument)JsonConvert.DeserializeXmlNode(json);

You can do JSON-to-XML also by using the .NET Framework (System.Runtime.Serialization.Json):
private static XDocument JsonToXml(string jsonString)
{
using (var stream = new MemoryStream(Encoding.ASCII.GetBytes(jsonString)))
{
var quotas = new XmlDictionaryReaderQuotas();
return XDocument.Load(JsonReaderWriterFactory.CreateJsonReader(stream, quotas));
}
}

DeserializeXmlNode returns XDcument.
If needed XNode use FirstNode.
//string jsonOutput="{"id":"108013515952807","posts":{"data":[{"id":"108013515952807_470186843068804","created_time":"2013-05-14T20:43:28+0000"},{"message":"TEKST","id":"108013515952807_470178529736302","created_time":"2013-05-14T20:22:07+0000"}";
var myelement= JsonConvert.DeserializeXmlNode(jsonOutput, "myelement").FirstNode;

Your shared JSON is invalid please go through http://jsonformatter.curiousconcept.com/ and validate your JSON first.
Yourt JSON should look like:
{
"id":"108013515952807",
"posts":{
"data":[
{
"id":"108013515952807_470186843068804",
"created_time":"2013-05-14T20:43:28+0000"
},
{
"message":"TEKST",
"id":"108013515952807_470178529736302",
"created_time":"2013-05-14T20:22:07+0000"
}
]
}
}

Adding on #jwaliszko's answer, converting json to XDocument:
XDocument xml = JsonConvert.DeserializeXNode(json);

Related

Converting from JSON to XML using c#

i have kind of wired requirement for converting JSON to xml.
we have an API that returns the JSON response as below.
{
"status":"Error",
"errorMessages":{
"1001":"Schema validation Error"
}
}
We want to convert this JSON to XML as below using c#
<root>
<status>ERROR</status>
<errorMessages>
<ErrorCode>1001</ErrorCode>
<ErrorDescription>Schema validation Error</ErrorDescription>
</errorMessages>
</root>
The API team is very resistant to change the way there are generating the JSON. So i have to find a way to convert this json to XML.
I am getting the below error when i try to convert
XmlDocument doc = JsonConvert.DeserializeXmlNode(json);
"JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifying a DeserializeRootElementName. Path errorMessages
thanks for the help in advance. :)
At first, I would hardly recommend that your API team provides a valid JSON object. Otherwise you will have to write a converter that does the job. The converter could look like this:
using System.Collections.Generic;
namespace Json
{
using System.IO;
using System.Xml.Serialization;
using Newtonsoft.Json.Linq;
class Program
{
static void Main(string[] args)
{
var converter = new Converter();
converter.Convert();
}
}
class Converter
{
public void Convert()
{
// your JSON string goes here
var jsonString = #"{""status"":""Error"",""errorMessages"":{ ""1001"":""Schema validation Error"", ""1953"":""Another error""}}";
// deconstruct the JSON
var jObject = JObject.Parse(jsonString);
var root = new Root { Status = jObject["status"].ToString(), ErrorMessages = new List<ErrorMessage>() };
foreach (var errorMessageJsonObject in jObject["errorMessages"])
{
var jProperty = (JProperty)errorMessageJsonObject;
var errorCode = System.Convert.ToInt16(jProperty.Name);
var errorDescription = jProperty.Value.ToString();
var errorMessage = new ErrorMessage() { ErrorCode = errorCode, ErrorDescription = errorDescription};
root.ErrorMessages.Add(errorMessage);
}
// serialize as XML
var xmlSerializer = new XmlSerializer(typeof(Root));
string xml;
using (StringWriter textWriter = new StringWriter())
{
xmlSerializer.Serialize(textWriter, root);
xml = textWriter.ToString();
}
}
}
public class Root
{
public string Status;
public List<ErrorMessage> ErrorMessages;
}
public class ErrorMessage
{
public int ErrorCode;
public string ErrorDescription;
}
}
With this, you will read the JSON, deconstruct it into a proper object and serialize it as XML.
if you are using asp.net web api. Its already can return xml response just add an accept header like
Accept: application/xml
From the documentation at https://www.newtonsoft.com/json/help/html/ConvertingJSONandXML.htm
string json = #"{
'?xml': {
'#version': '1.0',
'#standalone': 'no'
},
'root': {
'person': [
{
'#id': '1',
'name': 'Alan',
'url': 'http://www.google.com'
},
{
'#id': '2',
'name': 'Louis',
'url': 'http://www.yahoo.com'
}
]
}
}";
XmlDocument doc = (XmlDocument)JsonConvert.DeserializeXmlNode(json);
Use the JsonConvert class which contains helper methods for this precise purpose:
// To convert an XML node contained in string xml into a JSON string
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string jsonText = JsonConvert.SerializeXmlNode(doc);
// To convert JSON text contained in string json into an XML node
XmlDocument doc = JsonConvert.DeserializeXmlNode(json);
The Completed Documentation : Here

Hook OData's $metadata response and convert it from XML to JSON

The answer of Get OData $metadata in JSON format states that OData cannot return the metadata as JSON by default.
But is it possible then to capture or hook its response for the $metadata URL, and then convert it on the fly to JSON before sending it to the client?
I imagine pseudocode like this:
[HttpGet]
[ODataRoute("$metadata")]
public string GetMetadataAsJson()
{
string xml = GetOdataMetadataAsXML();
string json = ConvertToJson(xml);
return json;
}
I don't know how to implement it correctly, though, in particular I'm not sure how to get the standard OData response as a string, and how to hook the $metadata URL.
Newtonsoft supports the Json part checkout https://www.newtonsoft.com/json/help/html/ConvertXmlToJson.htm
So the actual solution for the Json Part would be quite simple, as soon as you have your XML
[HttpGet]
[ODataRoute("$metadata")]
public string GetMetadataAsJson()
{
string xml = GetOdataMetadataAsXML();
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string json = JsonConvert.SerializeXmlNode(doc);
return json;
}
Also you should probably first check if e.g. a format query is set for example with this code
[HttpGet]
[ODataRoute("$metadata")]
public string GetMetadataAsJson([FromQuery(Name="Format")]string format)
{
string metaResult = GetOdataMetadataAsXML();
if(format.Equals("json",StringComparison.OrdinalIgnoreCase))
{
XmlDocument metaDoc = new XmlDocument();
doc.LoadXml(metaResult);
metaResult = JsonConvert.SerializeXmlNode(doc);
}
return metaResult;
}

send list<xmldocument> to wcf, how to do it?

I'm trying to send List to wcf.
i want to send it as json, is there a way ?
when I'm trying to serialize, i get empty string, why ?
public string ImportXml(List<XmlDocument> docs,string token)
{
Account user = GetCurrentUser(token);
string url = string.Format("{0}ImportXml/{1}", ServiceUrl, user.Unumber);
string contentType = "text/json";
x.Serialize(Console.Out, docs);
string jsonReq = _serializer.Serialize(docs);
bool response = false;
HttpRequestHandler handler = new HttpRequestHandler();
string result = handler.HttpPostWithToken(url, jsonReq, contentType, token);
return result ;
}
Each element of the collection docs before sending into WCF is must be serialized into the JSON for example in this way:
string jsonText = JsonConvert.SerializeXmlNode(doc);
where doc is XmlDocument.
Or for Javascript in this way: Converting between XML and JSON
After you get collection of XmlDocument into WCF method try convert each element of entrance collection:
var documents = new List<XmlDocument>();
foreach (var doc in docs)
{
XmlDocument xmlDoc = JsonConvert.DeserializeXmlNode(doc);
documents.Add(xmlDoc);
}
finnally i got list of strings with xml in it.
it is much better, because that way we can work with anyone, and not only C#.
and i moved to newtonsoft instead JSS.
List<string>

Transform XML returned from a web request using XLST

I see several questions that are close to this but none exactly cover it:
How to apply an XSLT Stylesheet in C#
XSLT Transform of XML using Xml data from a web form
How to transform an xml structure generated from a request to a web services
I can cobble something together from these but I worry I am passing it through too many steps to be efficient.
What I currently have is this, to read XML from a HTTP web request:
WebRequest request = WebRequest.Create(url);
WebResponse response = request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader streamReader = new StreamReader(stream);
string xml = streamReader.ReadToEnd();
This was before the need to apply an XLST transform was needed. Now I have a (possibly null) XslCompiledTransform object.
So I want to add a block like:
if(transform != null)
{
xml = transform.Transform(xml);
}
Clearly this isn't possible as written. I see StringReaders and XmlReaders can be created but is it inefficient to get my xml as a string and then push it back into another object? Can I use my stream or streamReader objects directly to support the same basic flow, but with optional transformation?
Personally I'd use the XmlDocument.Load() function to load the XML from the URL, without using WebRequest in this case.
You can pass the XmlDocument Straight to XSLCompiledTransform.Transform() then.
XmlDocument doc = new XmlDocument();
doc.Load(url);
if (transform != null)
{
XmlDocument tempDoc = new XmlDocument();
using (XmlWriter writer = tempDoc.CreateNavigator().AppendChild())
{
transform.Transform(doc, writer);
}
doc = tempDoc;
} //Use your XmlDocument for your transformed output

How to Serialize XML to a JSON object with Json.NET

I can serialize XML to a JSON string like this:
var xml = new XmlDocument();
xml.LoadXml("<person><name>John</name></person>");
string jsonString = Newtonsoft.Json.JsonConvert.SerializeXmlNode(xml, Newtonsoft.Json.Formatting.None);
Response.ContentType = "application/json";
Response.Write(Newtonsoft.Json.JsonConvert.SerializeObject(jsonString));
That would give me:
"{\"person\":{\"name\":\"John\"}}"
But how can I serialize it to a JSON object? Like this:
{"person":{"name":"John"}}
Sometimes we just want to make it harder than it is ...
var xml = new XmlDocument();
xml.LoadXml("<person><name>John</name></person>");
Response.ContentType = "application/json";
Response.Write(Newtonsoft.Json.JsonConvert.SerializeObject(xml));
What I did wrong was to serialize the XML into a string and then serialize it again.
when you will access data then / automatically does not show .
I am accessing in HTML5 help of AJAX post .
Result is showing
in C# result is showing that "{\"person\":{\"name\":\"John\"}}"
But in HTML5 , it is working fine
{"person":{"name":"John"}}

Categories

Resources