Serializing XML with flat repeating structure - c#

I need to serialize some XML to an object. I don't have control over the structure of the XML so I'm stuck with this situation. The structure is similar to this example:
<A>
<B>Elements that are the stuff of B</B>
<C>Stuff about the stuff in B</C>
<B>Different stuff</B>
<C>Stuff about the different stuff</C>
<C>Some more stuff about the different stuff</C>
<B>Weird stuff</B>
<C>Stuff about the Weird Stuff</C>
<C>Still more stuff about the Weird Stuff</C>
<D>New thing that goes with the Weird Stuff</D>
<B>Things</B>
<C>Stuff about Things</C>
</A>
I'd like to get this serialized to an object that maintains the information about the sibling structure.
public class A
{
public List<BCD> BCD {get; set;}
}
public class BCD
{
public B Bfield {get; set;}
public List<C> Cfield {get; set;}
public D Dfield {get; set;}
}
public class B
{
// class details
}
public class C
{
// class details
}
public class D
{
// class details
}
When I try this, it doesn't work. Is there anything I can do to maintain that structure using the XMLSerializer?

So I kept looking around for a solution and came up with this which is not exactly what I was looking for. This class structure retains the order of the sibling elements within the collection but does not create objects to represent a discrete group of the siblings.
public class A
{
[XmlElementAttribute("B", typeof(B))]
[XmlElementAttribute("C", typeof(C))]
[XmlElementAttribute("D", typeof(D))]
public List<object> BCD {get; set;}
}
public class B
{
// class details
}
public class C
{
// class details
}
public class D
{
// class details
}
The end result is BCD is a collection of the B,C,D objects in the order they appear in the XML.

You can try below steps:
convert your xml to xslt using xsd.exe(feature of VS)
convert xslt to class again by using xsd.exe
try to serialize and deserialize your xml to this class object.
now you can play with this class object to perform any action.
Hope this will help..

Related

why doesnt my json string convert into c# objects? [duplicate]

I have some JSON:
{
"foo" : [
{ "bar" : "baz" },
{ "bar" : "qux" }
]
}
And I want to deserialize this into a collection. I have defined this class:
public class Foo
{
public string bar { get; set; }
}
However, the following code does not work:
JsonConvert.DeserializeObject<List<Foo>>(jsonString);
How can I deserialize my JSON?
That JSON is not a Foo JSON array. The code JsonConvert.DeserializeObject<T>(jsonString) will parse the JSON string from the root on up, and your type T must match that JSON structure exactly. The parser is not going to guess which JSON member is supposed to represent the List<Foo> you're looking for.
You need a root object, that represents the JSON from the root element.
You can easily let the classes to do that be generated from a sample JSON. To do this, copy your JSON and click Edit -> Paste Special -> Paste JSON As Classes in Visual Studio.
Alternatively, you could do the same on http://json2csharp.com, which generates more or less the same classes.
You'll see that the collection actually is one element deeper than expected:
public class Foo
{
public string bar { get; set; }
}
public class RootObject
{
public List<Foo> foo { get; set; }
}
Now you can deserialize the JSON from the root (and be sure to rename RootObject to something useful):
var rootObject = JsonConvert.DeserializeObject<RootObject>(jsonString);
And access the collection:
foreach (var foo in rootObject.foo)
{
// foo is a `Foo`
}
You can always rename properties to follow your casing convention and apply a JsonProperty attribute to them:
public class Foo
{
[JsonProperty("bar")]
public string Bar { get; set; }
}
Also make sure that the JSON contains enough sample data. The class parser will have to guess the appropriate C# type based on the contents found in the JSON.

Deserialize JSON from a file [duplicate]

I have some JSON:
{
"foo" : [
{ "bar" : "baz" },
{ "bar" : "qux" }
]
}
And I want to deserialize this into a collection. I have defined this class:
public class Foo
{
public string bar { get; set; }
}
However, the following code does not work:
JsonConvert.DeserializeObject<List<Foo>>(jsonString);
How can I deserialize my JSON?
That JSON is not a Foo JSON array. The code JsonConvert.DeserializeObject<T>(jsonString) will parse the JSON string from the root on up, and your type T must match that JSON structure exactly. The parser is not going to guess which JSON member is supposed to represent the List<Foo> you're looking for.
You need a root object, that represents the JSON from the root element.
You can easily let the classes to do that be generated from a sample JSON. To do this, copy your JSON and click Edit -> Paste Special -> Paste JSON As Classes in Visual Studio.
Alternatively, you could do the same on http://json2csharp.com, which generates more or less the same classes.
You'll see that the collection actually is one element deeper than expected:
public class Foo
{
public string bar { get; set; }
}
public class RootObject
{
public List<Foo> foo { get; set; }
}
Now you can deserialize the JSON from the root (and be sure to rename RootObject to something useful):
var rootObject = JsonConvert.DeserializeObject<RootObject>(jsonString);
And access the collection:
foreach (var foo in rootObject.foo)
{
// foo is a `Foo`
}
You can always rename properties to follow your casing convention and apply a JsonProperty attribute to them:
public class Foo
{
[JsonProperty("bar")]
public string Bar { get; set; }
}
Also make sure that the JSON contains enough sample data. The class parser will have to guess the appropriate C# type based on the contents found in the JSON.

Deserialize multi-type JSON array using DataContracts

Currently, I have some JSON data that I am attempting to deserialize using the DataContractJsonSerializer class. However, one of the arrays in the data contains multiple types of objects. Is there a way to deserialize this data properly? I am aware that a very similar question exists, but I would prefer not to use Json.NET or any other third-party libraries.
EDIT: A small example:
In this instance, let's say the JSON is of form [{"foo":string},{"bar":string},{"foo":string},{"foo":string},...] where each element is either of form {"foo":string} or {"bar":string}. Then, the contracts could be set up as such:
[DataContract]
class Foo { [DataMember] public string foo; }
[DataContract]
class Bar { [DataMember] public string bar; }
In this context, my question is, how do I deserialize this array of Foos and Bars?
This does not sound right. There should not be two completely different types in a single array. Given the JSON provided I would try something like this....
[DataContract]
class SomeClass
{
[DataMember]
public string foo { get; set;}
[DataMember]
public string bar { get; set;}
}
Then check for IsNullOrWhiteSpace() on each property.
Updated with more code...
static void Main(string[] args)
{
SomeClass[] output;
var json = "[{\"foo\":\"value\"},{\"bar\":\"value\"},{\"foo\":\"value1\"},{\"foo\":\"value1\"}]";
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))
{
var deserializer = new DataContractJsonSerializer(typeof(SomeClass[]));
output = (SomeClass[])deserializer.ReadObject(ms);
}
// do something with output
Console.WriteLine(output.Length);
}

Format XML containing List for Deserialization

I have some data which I need to bring from an XML file to a PostgreSQL database through a C# application I am currently working on.
The problem I face now is that I need to add some kind of list to the XML now. Currently it looks something like this:
<itemOne>stuff</itemOne>
<itemTwo>otherStuff</itemTwo>
<listOfItems>
<listItem>
<partOne>123</partOne>
<partTwo>abc</partTwo>
</listItem>
<listItem>
<partOne>123</partOne>
<partTwo>abc</partTwo>
</listItem>
</listOfItems>
So I found quite some threads which handle the topic of how to deserialize lists. But all of them start by saying that the proposed XML should be modified. As I have all the freedom that I could wish for in that regard, I'd like to first create an optimal XML format at first.
Well, and afterwards deserialize it. So if there is any format for lists which is automatically processed by XmlSerializer.Deserialize() it would be amazing.
That data will already be processed automatically by XmlSerializer, as long as the class is shaped to match. For example:
[XmlRoot("yourRootName")]
public class Foo {
[XmlElement("itemOne")] public string A {get;set;}
[XmlElement("itemTwo")] public string B {get;set;}
[XmlArray("listOfItems")]
[XmlArrayItem("listItem")]
public List<Bar> Bars {get;set;}
}
public class Bar {
[XmlElement("partOne")] public int C {get;set;}
[XmlElement("partTwo")] public string D {get;set;}
}
Of course, if it was me I'd be tempted to be terse, with:
<betterName foo="stuff" blab="otherStuff">
<nameMe a="123" b="abc"/>
<nameMe a="456" b="def"/>
</betterName>
which just requires some minimal changes:
[XmlRoot("betterName")]
public class Foo {
[XmlAttribute("foo")] public string A {get;set;}
[XmlAttribute("bar")] public string B {get;set;}
[XmlElement("nameMe")]
public List<Bar> Bars {get;set;}
}
public class Bar {
[XmlAttribute("a")] public int C {get;set;}
[XmlAttribute("b")] public string D {get;set;}
}

How can I read data from a serialized object whose definition isn't in my code base any more?

Say I have the following class:
[Serializable]
public class A
{
public string B { get; set; }
}
and the following method was used to serialize it:
public void Serialize()
{
BinaryFormatter b = new BinaryFormatter();
b.Serialize(new FileStream(#"C:\Temp\out.dat", FileMode.Create), new A());
}
If at some point, someone came along and modified the class definition to contain an extra property (or remove one):
[Serializable]
public class A // Same class
{
public string B { get; set; }
public string C { get; set; } // New property
}
then the following will break:
public void Deserialize()
{
BinaryFormatter b = new BinaryFormatter();
A deserialized = (A)b.Deserialize(new FileStream(#"C:\Temp\out.dat", FileMode.Open));
}
because the serialized version of the class does not match the class definition of the new class.
I really dislike the idea of serialization as a persistence mechanism because it's so fragile. I would have dealt with this much earlier if I had been involved in the decision.
Is there any way to get my serialized data into a form I can read it without reverting all of my current class definitions to their serialized state?
Even if it's hacky "to the max", I was hoping I could do this, because I would hopefully only do it once (or until I could figure out how to fix the root of the problem).
edit
There are dozens of these classes that have been serialized and then modified in my system already. It is not feasible to use version control to see exactly when and how each individual class changed.
I'm currently trying to figure out a way I can retain "old A"'s settings before the user tries to deserialize the object to the "new A" format and I have to 1) try, 2) catch, 3) swallow the error, and finally 4) recreate A with default values (based on the new object definition).
I believe that you can decorate newly added members with the OptionalFieldAttribute (System.Runtime.Serialization namespace), which will allow you to deserialize instances that were serialized before that member was added.
[Serializable]
public class A // Same class
{
public string B { get; set; }
[OptionalField] public string C { get; set; } // New property
}

Categories

Resources