Reputation: 11
Good evening. I have an XML structure like this:
string cRet = "<bands>";
cRet += "<artist>";
cRet += "<name>";
cRet += "Vasco";
cRet += "</name>";
cRet += "<lp>";
cRet += "<namelp>";
cRet += "Bollicine";
cRet += "</namelp>";
cRet += "<songs>";
cRet += "<song>";
cRet += "Bollicine";
cRet += "</song>";
cRet += "<song>";
cRet += "Vita Spericolata";
cRet += "</song>";
cRet += "<song>";
cRet += "Giocala";
cRet += "</song>";
cRet += "</songs>";
cRet += "</lp>";
cRet += "<lp>";
cRet += "<namelp>";
cRet += "Gli SPari Sopra";
cRet += "</namelp>";
cRet += "<songs>";
cRet += "<song>";
cRet += "Gli SPari Sopra";
cRet += "</song>";
cRet += "<song>";
cRet += "Gabri";
cRet += "</song>";
cRet += "<song>";
cRet += "Lo Show";
cRet += "</song>";
cRet += "</songs>";
cRet += "</lp>";
cRet += "</artist>";
cRet += "</bands>";
var serializer = new XmlSerializer(typeof(Root));
var root = (Root)serializer.Deserialize(new StringReader(cRet));
string cJson = JsonConvert.SerializeObject(root, Newtonsoft.Json.Formatting.Indented);
I define:
[XmlRoot("bands"), JsonObject]
public class Root
{
[XmlElement, JsonProperty]
public string name { get; set; }
[XmlElement, JsonProperty]
public string albumName { get; set; }
[XmlElement, JsonProperty]
public string song { get; set; }
}
I obtain:
{ "name": null, "albumName": null, "song": null }
If I use one level only I get perfect result. How can I define "artist" and "album"?
Upvotes: 0
Views: 66
Reputation: 4991
Do you have Visual Studio 2017/2019? If so you can Generate Class From JSON or XML in Visual Studio . Once you have properly defined classes you should be able to use Newtonsoft.Json to create your json.
To create the classes from XML do the following:
Create your sample XML:
Note: If any element in your XML has multiple elements, ensure your sample data includes multiple elements.
<bands>
<artist>
<name>Vasco</name>
<lp>
<namelp>Bollicine</namelp>
<songs>
<song>Bollicine</song>
<song>Vita Spericolata</song>
<song>Giocala</song>
</songs>
</lp>
</artist>
<artist>
<name>Other Artist</name>
<lp>
<namelp>Other Artist album name</namelp>
<songs>
<song>Song 1</song>
<song>Song 2</song>
</songs>
</lp>
</artist>
</bands>
Open Visual Studio 2017 (or 2019)
Create new Project (File => New Project => ...)
Add using statement: using System.Xml.Serialization;
Create new class (Project => Add Class...) name: bands
Open your sample XML in Notepad.
Highlight the XML, right-click, and select Copy
In VS menu, click Edit
Select Paste special
Select Paste XML As Classes
You'll get the following:
// NOTE: Generated code may require at least .NET Framework 4.5 or .NET Core/Standard 2.0.
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class bands
{
private bandsArtist[] artistField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("artist")]
public bandsArtist[] artist
{
get
{
return this.artistField;
}
set
{
this.artistField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class bandsArtist
{
private string nameField;
private bandsArtistLP lpField;
/// <remarks/>
public string name
{
get
{
return this.nameField;
}
set
{
this.nameField = value;
}
}
/// <remarks/>
public bandsArtistLP lp
{
get
{
return this.lpField;
}
set
{
this.lpField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class bandsArtistLP
{
private string namelpField;
private string[] songsField;
/// <remarks/>
public string namelp
{
get
{
return this.namelpField;
}
set
{
this.namelpField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlArrayItemAttribute("song", IsNullable = false)]
public string[] songs
{
get
{
return this.songsField;
}
set
{
this.songsField = value;
}
}
}
I modified/refactored the code a little bit and ended up with the code below. I changed the case of the class names. Also, to order elements of the same depth in the desired order, I added interfaces for some of the classes (as described in .NET Serialization Ordering)
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false, ElementName = "bands")]
public partial class Bands
{
[System.Xml.Serialization.XmlElementAttribute("artist")]
public List<BandsArtist> artist { get; set; } = new List<BandsArtist>();
}
public interface IBandsArtist
{
string name { get; set; }
List<BandsArtistLP> lp { get; set; }
}
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class BandsArtist : IBandsArtist
{
[XmlElement("name")]
public string name { get; set; }
[System.Xml.Serialization.XmlElementAttribute("lp")]
public List<BandsArtistLP> lp { get; set; } = new List<BandsArtistLP>();
}
public interface IBandsArtistLP
{
string namelp { get; set; }
List<string> songs { get; set; }
}
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class BandsArtistLP : IBandsArtistLP
{
[XmlElement("namelp")]
public string namelp { get; set; }
[XmlArrayItemAttribute("song", IsNullable = false)]
public List<string> songs { get; set; } = new List<string>();
}
Use Newtonsoft.json to serialize the "bands" class (where "myBands" is an instance of class "bands" that contains your data)
string cJson = JsonConvert.SerializeObject(myBands, Newtonsoft.Json.Formatting.Indented);
The resulting json is:
{
"artist": [
{
"name": "Vasco",
"lp": [
{
"namelp": "Bollicine",
"songs": [
"Bollicine",
"Vita Spericolata",
"Giocala"
]
}
]
},
{
"name": "Other Artist",
"lp": [
{
"namelp": "Other Artist album name",
"songs": [
"Song 1",
"Song 2"
]
}
]
}
]
}
Upvotes: 1