Jsonconvert - 如何定义结构
Posted
技术标签:
【中文标题】Jsonconvert - 如何定义结构【英文标题】:Jsonconvert - How to define structure 【发布时间】:2021-03-24 11:02:13 【问题描述】:晚上好。我有一个这样的 XML 结构:
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);
我定义:
[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;
我得到:
"name": null, "albumName": null, "song": null
如果我只使用一个级别,我会得到完美的结果。 如何定义“艺术家”和“专辑”?
【问题讨论】:
你调试过你的代码吗?root
在 XML 反序列化之后是否包含任何内容?对于它的价值,这是一种创建 XML 字符串(所有字符串连接)的低效方式
你想要的输出是什么?
【参考方案1】:
您有 Visual Studio 2017/2019 吗?如果是这样,您可以 Generate Class From JSON or XML in Visual Studio 。正确定义类后,您应该可以使用 Newtonsoft.Json 创建您的 json。
要从 XML 创建类,请执行以下操作:
创建您的示例 XML:
注意:如果您的 XML 中的任何元素包含多个元素,请确保您的示例数据包含多个元素。
<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>
打开 Visual Studio 2017(或 2019)
创建新项目(文件 => 新项目 => ...)
添加using语句:using System.Xml.Serialization;
创建新类(Project => Add Class...)名称:bands
在记事本中打开您的示例 XML。
突出显示 XML,右键单击并选择 复制
在 VS 菜单中,点击编辑
选择选择性粘贴
选择将 XML 粘贴为类
您将获得以下信息:
// 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;
我稍微修改/重构了代码,最终得到了下面的代码。我改变了类名的大小写。此外,为了按所需顺序对相同深度的元素进行排序,我为某些类添加了接口(如.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>();
使用 Newtonsoft.json 序列化“bands”类(其中“myBands”是包含您的数据的“bands”类的实例)
string cJson = JsonConvert.SerializeObject(myBands, Newtonsoft.Json.Formatting.Indented);
生成的 json 为:
"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"
]
]
]
【讨论】:
以上是关于Jsonconvert - 如何定义结构的主要内容,如果未能解决你的问题,请参考以下文章
JsonConvert.SerializeObject - 自定义 ContracteResolver 不为多次调用调用 CreateProperty
Newtonsoft.Json.JsonConvert 从同一个类中序列化和反序列化
如何使用 JSONConvert 将变量 Result 转换为对象?
如何使用 JsonConvert 从包含空数组的 JSON 字符串中获取 DataTable?
如何调用 JsonConvert.DeserializeObject 并禁用通过 [JsonConverter] 应用于基本类型的 JsonConverter?