I'm trying to generate an indented JSON output using JSON.Net. The first code does not work
var data = new WebClient().DownloadString(url);
var json = JsonConvert.SerializeObject(data, Formatting.Indented);
However, this second code does work
var data = new WebClient().DownloadString(url);
var json = JValue.Parse(data).ToString(Formatting.Indented);
I'm a bit confused why both versions don't give the same output.
Related
string inputxml = "<transaction>
<node1>value1</node1>
<node2>value2</node2>
<node3>value3</node3>
</transaction>"
I want to convert this XML string to JSON string in the below format after omitting the outermost node:
{"node1";"value1","node2":"value2","node3":"value3"}
You can use :
1 - XDocument to build anonymous object that match the Json like :
string inputxml = #"<transaction>
<node1>value1</node1>
<node2>value2</node2>
<node3>value3</node3>
</transaction>";
var node = XDocument.Parse(inputxml)
.Descendants("transaction")
.Select(x => new
{
Node1 = x.Element("node1").Value,
Node2 = x.Element("node2").Value,
Node3 = x.Element("node3").Value
}).FirstOrDefault();
2 - Newtonsoft to serialize the object like :
string json = JsonConvert.SerializeObject(node);
Demo
Console.WriteLine(json);
Result
{"Node1":"value1","Node2":"value2","Node3":"value3"}
I hope you find this helpful.
As far as i understood your problem you do not have model neither for source XML nor for JSON and names can chenge in future, so we shouldn't use strict names. So we will try to build it dynamically. Pay attention - u'll need to use Newtonsoft.Json nuget pack.
string inputxml = #"<transaction>
<node1>value1</node1>
<node2>value2</node2>
<node3>value3</node3>
</transaction>";
XDocument xdoc = XDocument.Parse(inputxml); //parse XML document
var jprops = xdoc.Root.Elements() // take elements in root of the doc
.Select(x => (x.Name, x.Value)) // map it to tuples (XName, string)
.Select(x => new JProperty(x.Name.LocalName, x.Value)); //map it to enumerbale of Json properties
JObject resultingObj = new JObject(jprops); // construct your json and populate its contents
Console.WriteLine(resultingObj.ToString()); // Write out - u r awesome
I have an XML file and I want to convert to BsonArray in MongoDB, later then I can make it a list of elements. Here is what I tried.
XmlDocument doc = new XmlDocument();
doc.Load("Books.xml");
string json_doc = JsonConvert.SerializeXmlNode(doc);
...
using (var jsonReader = new JsonReader(json_doc))
{
var context = BsonDeserializationContext.CreateRoot(jsonReader);
var document = XML_collection.DocumentSerializer.Deserialize(context);
}
Code converts XML to Json but not BsonArray. That means what I will get is only ONE document with hundreds of fields. But what I want is making them separate as a list.
You can use BsonDocument.Parse() to read your string and then you can access catalog.book path to cast into BsonArray:
var json_doc = JsonConvert.SerializeXmlNode(doc);
var bsonArray = BsonDocument.Parse(json_doc)["catalog"]["book"].AsBsonArray;
I have a C# file which was auto generated by using the wsdl.exe utility.
This file contains the "MyObject" class used in the code example below.
I am now trying to Deserialize the raw response of the webservice to the object model manually.
The XML structure looks like this:
<?xml version="1.0">
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope">
<soap:Body>
<ns2:myResponse xmlns:ns2="http://myurl.com">
<return>...</return>
<return>...</return>
<return>...</return>
...
</ns2:myResponse>
</soap:Body>
</soap:Envelope>
The following code works for deserializing the "return" elements to "MyObject":
var file = #"C:\Data\example_response.xml";
var xdoc = XDocument.Load(file);
var myNamespace = "http://myurl.com";
var results = xdoc.Descendants(XName.Get("myResponse", myNamespace)).Elements();
var myObjects = new List<MyObject>();
foreach (var result in results)
{
XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "return";
xRoot.IsNullable = true;
var serializer = new XmlSerializer(typeof(MyObject), xRoot);
var output = (MyObject)serializer.Deserialize(result.CreateReader());
myObjects.Add(myObject);
}
The problem is the above code is terribly slow. It takes 6 secondes to iterate over 400 "return" elements.
It would probably be advised to run the XmlSerializer Deserialize method outside of the foreach-loop, but I am unable to get this working with the code below:
var file = #"C:\Data\example_response.xml";
var xdoc = XDocument.Load(file);
var myNamespace = "http://myurl.com";
var results = xdoc.Descendants(XName.Get("myResponse", myNamespace)).ElementAt(0).ToString();
XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.Namespace = myNamespace;
xRoot.ElementName = "myResponse";
xRoot.IsNullable = true;
var serializer = new XmlSerializer(typeof(List<MyObject>), xRoot);
var output = (List<MyObject>)serializer.Deserialize(new StringReader(results));
The code above is resulting into an empty list (probably because the XmlSerializer does not recognize the "return" element to be a "MyObject", but I don't want to make changes to the generated C# file.
I feel like there's a terribly easy solution for my problem, but I can't seem to figure it out.
I want to convert a XML file to BSON. then import the BSON to MongoDB. I searched but could not find how to covert this using C#. please provide me a source code to do this using C#
Had the same Problem today.
It's for sure not the best solution, but
i solved it this way in my project and it works for what i need it:
Deserialize XML to Json
Deserialize Json to Bson
using (var reader = new StreamReader(context.Request.Body))
{
var body = reader.ReadToEnd(); // read input string
XmlDocument doc = new XmlDocument();
doc.LoadXml(body); // String to XML Document
string jsonText = JsonConvert.SerializeXmlNode(doc); //XML to Json
var bsdocument = BsonSerializer.Deserialize<BsonDocument>(jsonText); //Deserialize JSON String to BSon Document
var mcollection = Program._database.GetCollection<BsonDocument>("test_collection_05");
await mcollection.InsertOneAsync(bsdocument); //Insert into mongoDB
}
I feel like I am going made. I have written a hundred deserializing routines, but this one is killing me!
Below is what I get returned from a service. A very simple array of strings...I think.
<ArrayOfstring xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<string>Action & Adventure</string>
<string>Comedy</string>
<string>Drama</string>
<string>Family</string>
<string>Horror</string>
<string>Independent & World</string>
<string>Romance</string>
<string>Sci-Fi/Fantasy</string>
<string>Thriller & Crime</string>
</ArrayOfstring>
I am using out the box deserializing
var serializer = new XmlSerializer(typeof(List<string>));
var reader = new StringReader(xmlString);
var GenreList = (List<string>)serializer.Deserialize(reader);
but I get the following error on the Deserialize line:
<ArrayOfstring xmlns='http://schemas.microsoft.com/2003/10/Serialization/Arrays'> was not expected
I have tried including the namespace and creating all manner of exotic objects in an attempt to get this to work. Crazy amount of time. In the end I have requested it in JSON and deserialised that with Json.net.
However I am curious as to what I have been doing wrong!
Of course XmlSerializer can deserialize it. All you need is to create XmlSerializer as follows
var serializer = new XmlSerializer(typeof(List<string>),
new XmlRootAttribute() { ElementName = "ArrayOfstring", Namespace = "http://schemas.microsoft.com/2003/10/Serialization/Arrays" });
The XML Serializer cannot deserialize a simpletype or a list of simple types without additional specification, but the DataContractReader can:
string content = #"
<ArrayOfstring xmlns=""http://schemas.microsoft.com/2003/10/Serialization/Arrays"" xmlns:i=""http://www.w3.org/2001/XMLSchema-instance"">
<string>Action & Adventure</string>
<string>Comedy</string>
<string>Drama</string>
<string>Family</string>
<string>Horror</string>
<string>Independent & World</string>
<string>Romance</string>
<string>Sci-Fi/Fantasy</string>
<string>Thriller & Crime</string>
</ArrayOfstring>";
var serializer = new DataContractSerializer(typeof(string[]));
var reader = new XmlTextReader(new StringReader(content));
var GenreList = new List<string>((string[])serializer.ReadObject(reader));
You can also use a simple class to achieve the same results. Note that I removed the namespaces from your XML file for brevity. You can implement reading of the namespaces in the serializer if you please.
public class ArrayOfstring
{
[XmlElement("string")]
public List<string> strings;
}
private void Deserialize(string xmlString)
{
var serializer = new XmlSerializer(typeof(ArrayOfstring));
var reader = new StringReader(xmlString);
var GenreList = ((ArrayOfstring) serializer.Deserialize(reader)).strings;
}
This will work
DataContractSerializer xmlSer = new DataContractSerializer(typeof(string[]));
TextReader reader=new StreamReader(xmlString);
var stringArr= (string[])xmlSer.ReadObject(reader);
List<string> listStr=new List<>();
for(var s in stringArr)
{
listStr.Add(s);
}
I realize this is an old question, but I recently ran on to the same issue and wanted to share what worked for me. I tried all the approaches outlined as potential solutions, but couldn't get any of them to work. Even specifying the namespace in the XmlRootAttribute approach would throw the "was not expected" error reported in the original problem. I was getting the ArrayOfString as a response from an API, so I used an XDocument parse approach:
List<string> lstGenre = new List<string>();
var response = await client.PostAsync(url, content);
var responseString = await response.Content.ReadAsStringAsync();
XDocument xdoc = XDocument.Parse(responseString);
XNamespace ns = xdoc.Root.GetDefaultNamespace();
XElement root = xdoc.Element(XName.Get("ArrayOfString", ns.NamespaceName));
IEnumerable<XElement> list = root.Elements();
foreach (XElement element in list)
{
string item = element.Value; // <-- individual strings from the "ArrayOfString"
lstGenre.Add(item);
}