Converting JSON Array Entries to XML - c#

I wanted to convert the JSON data into XML contains the JSON array entries into the same. JSON data which I am converting is as below
{
"userName":[
"user1",
"user2"
],
"referenceNumber":"098784866589157763",
"responseCode":"00",
"responseDesc":"Success."
}
To convert the JSON to XML using below C# code
XmlDocument doc = JsonConvert.DeserializeXmlNode(jsonData, "response");
which is converting JSON to below XML
<response>
<userName>user1</userName>
<userName>user2</userName>
<referenceNumber>098784866589157763</referenceNumber>
<responseCode>00</responseCode>
<responseDesc>Success.</responseDesc>
</response>
but expected output XML is as below
<response>
<userName>
<element>user1</element>
<element>user2</element>
</userName>
<referenceNumber>098784866589157763</referenceNumber>
<responseCode>00</responseCode>
<responseDesc>Success.</responseDesc>
</response>
Is there any way to achieve the same?

If you can use the LINQ to XML, which is elegant way to manipulate XML documents, then
below is one of the ways to achieve the requirement:
XElement root = JsonConvert.DeserializeXNode(jsonData, "response").Root;
// Create elements for userName in new XML
var docFinal = new XDocument(new XElement("response" , new XElement("userName",
from user in root.Descendants("userName") select new XElement("element", user.Value))));
//Add remaining XML Attributs
docFinal.Root.Add(root.Elements()
.Select(x => new XElement(x.Name, x.Value)).Where(x => x.Name != "userName"));
//OUTPUT
//<response>
// <userName>
// <element>user1</element>
// <element>user2</element>
// </userName>
// <referenceNumber>098784866589157763</referenceNumber>
// <responseCode>00</responseCode>
// <responseDesc>Success.</responseDesc>
//</response>

Related

i want to fetch array of record in xml using c# Linq

this is my code to fetch xml values from files and it does successfully but single element like an in file type but when i try to fetch array of records from xml it failed
public void readXmlFiles()
{
var xml = XDocument.Load(#"C:\Applications\Files\Xmldemo.xml");
var format = from r in xml.Descendants("insureance")
select new
{
type = r.Element("type").Value,
// values=r.Element("value").Value
};
foreach (var r in format)
{
Console.WriteLine(r.values);
}
}
this is my xml file
<?xml version="1.0" encoding="UTF-8"?>
<insureance>
<type>Risk</type>
<classofbusiness type="array">
<value>0</value>
<value>1</value>
<value>2</value>
</classofbusiness>
</insureance>
now i want to fetch classofbusiness all values thanx in advance
Your current attempt selects a single value element, which doesn't exist as a child of insureance. I would guess you get a null reference exception as a result.
You need to follow the structure of the document
var format =
from ins in doc.Descendants("insureance")
select new
{
Type = (string) ins.Element("type"),
ClassOfBusiness = ins.Elements("classofbusiness")
.Elements("value")
.Select(x => (int) x)
.ToArray()
};
var format = xml.Elements("insureance").Elements("classofbusiness").Descendants();

c# LINQ to XML - XDocument

Just trying to read a simple XML doc in using XDocument class.
The document is read, but I'm struggling mapping my OperationConfig to the XML?
var xml = XDocument.Load(path);
var query = xml.Root.Elements("configaccount")
.Select(o => new OperationConfig()
{
AccountName = o.Attribute("accountname").Value,
Email = o.Attribute("email").Value
});
The XML:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<configaccount>
<accountname>
BusinessName
</accountname>
<email>
aa#domain.com
</email>
</configaccount>
</Config>
Not sure what I've missed as I'm retuning null?
You need to retrive Descendants node by name from xml. Also "accountname" and "email" is not an attributes, its an Element of XML. Attributes are inside element.
Replace your query
var query = xml.Descendants("configaccount")
.Select(o => new OperationConfig
{
AccountName = o.Element("accountname").Value,
Email = o.Element("email").Value
});
Hope this help

Json data remove unwanted elements

I have the following in some json I have converted from XML:
"ForSaleStatus":{"items":{"item":{"label":"Not For Sale","value":"2"}}}
This was some xml an application generated from a dropdown. I want to convert it to this in C#:
"ForSaleStatus":"2"
Here is the code I have so far:
var xml = i;
var root = XElement.Parse(xml);
// remove ALL empty elements such as <items/>
root.Descendants().Where(e => string.IsNullOrEmpty(e.Value)).Remove();
// convert the node to JSON for easier processing
var json = JsonConvert.SerializeXNode(root);
Can anyone think of a way of converting the json or am I better off going back to the XML and working on that?
The XML looks like this:
<ForSaleStatus>
<items>
<item>
<label>Not For Sale</label>
<value>2</value>
</item>
</items>
</ForSaleStatus>
It would be easier to extract the values you want and just construct the json from that :
var json = JsonConvert.SerializeObject(new Dictionary<string, string>
{
[root.Name.ToString()] = root.XPathSelectElement("items/item/value").Value
});
If that doesn't compile for you, use this older syntax :
var json = JsonConvert.SerializeObject(new Dictionary<string, string>
{
{ root.Name.ToString(), root.XPathSelectElement("items/item/value").Value }
});
Edit: in case you need values from all the items :
var json = JsonConvert.SerializeObject(root
.XPathSelectElements("items/item")
.ToDictionary(
x => x.XPathSelectElement("label").Value,
x => x.XPathSelectElement("value").Value
));

xml Nodes by Element

Below is an example of the xml file that I need to pull data via C#. This is my first experience with reading xml files and a beginner with xml. Anyone have an example of how I would find/load the fieldorder values for Export_B?
<?xml version="1.0" encoding="utf-8"?>
<Config>
<OutFolderCSV>c:\Output\2012\upload_Files</OutFolderCSV>
<OutFolderImage>c:\Output\2012\NM_Scorecard_Images</OutFolderImage>
<PathOutLogFile>c:\Output\2012\Log\Matches.log</PathOutLogFile>
<FieldSeparator>,</FieldSeparator>
<ExportFile>
<Name>Export_A</Name>
<FieldOrder>matchID</FieldOrder>
<FieldOrder>contactID</FieldOrder>
<FieldOrder>stageID13</FieldOrder>
<FieldOrder>stringScore1a</FieldOrder>
<FieldOrder>xScore1a</FieldOrder>
<FieldOrder>stageID14</FieldOrder>
<FieldOrder>stringScore1b</FieldOrder>
<FieldOrder>xScore1b</FieldOrder>
<FieldOrder>stageID15</FieldOrder>
<FieldOrder>stringScore1c</FieldOrder>
<FieldOrder>xScore1c</FieldOrder>
</ExportFile>
<ExportFile>
<Name>Export_B</Name>
<FieldOrder>matchID</FieldOrder>
<FieldOrder>contactID</FieldOrder>
<FieldOrder>stageID16</FieldOrder>
<FieldOrder>stringScore1a</FieldOrder>
<FieldOrder>xScore1a</FieldOrder>
<FieldOrder>stageID17</FieldOrder>
<FieldOrder>stringScore1b</FieldOrder>
<FieldOrder>xScore1b</FieldOrder>
<FieldOrder>stageID18</FieldOrder>
<FieldOrder>stringScore1c</FieldOrder>
<FieldOrder>xScore</FieldOrder>
</ExportFile>
</Config>
Using LINQ to XML:
var doc = XDocument.Load(#"c:\path\to\file.xml");
var fieldOrders =
from exportFile in doc.Descendants("ExportFile")
where (string)exportFile.Element("Name") == "Export_B"
from fieldOrder in exportFile.Elements("FieldOrder")
select (string)fieldOrder;
I have written an article
http://www.codeproject.com/Articles/33769/Basics-of-LINQ-Lamda-Expressions
on XML using XDocument object.
You can parse the XML easily using
XDocument.Load(filepath)
Please read the section XLinq to parse the objects.
edit :
You can change value of Export_B using the code :
var document = XDocument.Load(filepath)
var exportFiles = document.Descandants("ExportFile");
List<XElement> list = new List<XElement>();
foreach(var element in exportFiles)
{
list.Add(element);
// Now you can do element.Element("Name") to get the name. Put a breakpoint on this, you can get the reference of all underlying objects.
}

XmlSerializer Deserializing Array/List of Multiple Objects at Root

I'm trying to deserialize the following XML output:
<?xml version="1.0" encoding="ISO-8859-1"?>
<Foo>
<Val>Data1</Val>
</Foo>
<Foo>
<Val>Data2</Val>
</Foo>
(This is output from a hardware device, and cannot be changed)
I have an XML type defined as:
[XmlType(AnonymousType=true, Namespace="")]
public class Foo
{
public string Val { get; set; }
}
I've tried to deserialize this array by creating a serializer like:
var s = new XmlSerializer(typeof(Foo[]));
//or
var s = new XmlSerializer(typeof(List<Foo>);
But every call to s.Deserialize() causes an InvalidOperaitonException:
System.InvalidOperationException: <Foo xmlns=''> was not expected.
Note
var s = new XmlSerializer(typeof(Foo));
// Only deseralizes the first Foo (Data1).
Thanks for your help.
I think the issue is with your provided xml.
Test app says
List<Foo> list = new List<Foo> {new Foo {Val = "Data1"}, new Foo {Val = "Data2"}};
var s = new XmlSerializer(typeof(List<Foo>));
StringBuilder sb = new StringBuilder();
XmlWriter wr = XmlWriter.Create(sb);
s.Serialize(wr, list);
string ss = sb.ToString();
var s2 = new XmlSerializer(typeof(List<Foo>));
StringReader sr = new StringReader(ss);
List<Foo> returnList = (List<Foo>)s2.Deserialize(sr);
And the XML should be
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfFoo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Foo>
<Val>Data1</Val>
</Foo>
<Foo>
<Val>Data2</Val>
</Foo>
</ArrayOfFoo>
If you can remove the inital line
<?xml version="1.0" encoding="ISO-8859-1"?>
And minipulate the string into
string s = "<ArrayOfFoo><Foo> <Val>Data1</Val></Foo><Foo> <Val>Data2</Val></Foo></ArrayOfFoo>";
var s2 = new XmlSerializer(typeof(List<Foo>));
StringReader sr = new StringReader(s);
List<Foo> list = (List<Foo>)s2.Deserialize(sr);
That could work.
That isn't valid Xml. There needs to be a core root element for it to work properly.
this is not a valid xml so you can not deserialize it like a valid xml. You need some kind of hack to make this work. i'd suggest to insert at beginning of the xml and inserting at the end of xml. then you can deserialize it, since you cant make this change at xml side, do it in your code.
String ss;
// lets assume this holds your xml data in string.
ss.append("</ArrayOfFoo>");
ss.replace("<?xml version=\"1.0\" encoding=\"utf-16\"?>", "<?xml version=\"1.0\" encoding=\"utf-16\"?> <ArrayOfFoo>")
var s2 = new XmlSerializer(typeof(List<Foo>));
StringReader sr = new StringReader(ss);
List<Foo> returnList = (List<Foo>)s2.Deserialize(sr);
now this shall return you the correct list.
As the other posters say, this XML that the hardware device produces is not compatible to the way .NET serializes/deserializes object. Valid XML, and .NET requires valid XML, has a root element.
I suggest:
either you modify your obtained XML to match the way astander presents in his xml code snippet.
or you write a simple xml parser for your file that deserializes the file like you need
br, Marcel
Technically, what you have there is not a well-formed XML document (which has exactly one root element), but rather an well-formed external parsed entity (which can have any number of elements not contained in other elements, as well as text not contained in any elements). Therefore, it should parse if your XML parser has an entry point for parsing EPEs rather than documents. You could also create a stub document which includes by reference your EPE and parse that document.
Xstream for .Net could be a useful API

Categories