英文:
C# Problem deserialize XML into JSON array
问题
我有以下的XML:
<table>
<name>Table 1</name>
<headers>
<header>Header 1</header>
<header>Header 2</header>
</headers>
<data>
<row>
<row_item>Item 1</row_item>
<row_item>Item 2</row_item>
</row>
<row>
<row_item>Item 3</row_item>
<row_item>Item 4</row_item>
</row>
</data>
</table>
现在我可以使用内置的XmlSerializer类轻松反序列化它,使用以下类:
[JsonObject("table")]
[XmlRoot("table")]
public class Table
{
[JsonProperty("name")]
[XmlElement("name")]
public string Name { get; set; }
[JsonProperty("headers")]
[XmlArray("headers"), XmlArrayItem("header")]
public List<string> Headers { get; set; } = new List<string>();
[JsonProperty("data")]
[XmlArray("data"), XmlArrayItem("row")]
public List<DataRow> Data { get; set; } = new List<DataRow>();
}
public class DataRow
{
[XmlElement("row_item")]
public List<string> DataRowItems { get; set; }
}
现在我需要将其转换为JSON,我正在使用Newtonsoft来完成这个任务,但我面临的问题是当前的类结构会将 "DataRowItems" 添加到JSON 中。
{
"table": [
{
"data": [
{
"DataRowItems": [
"Item 1",
"Item 2"
]
},
{
"DataRowItems": [
"Item 3",
"Item 4"
]
}
],
"headers": [
"Item 1",
"Item 2",
"Item 3"
],
"name": "Some text"
}
]
}
而我需要将 "data" 元素作为数组的数组发送,就像这样:
{
"table": [
{
"data": [
["Item 1", "Item 2", "Item 3"],
["Item 4", "Item 5", "Item 6"]
],
"headers": ["Column 1", "Column 2", "Column 3"],
"name": "Some text"
}
]
}
如何实现这一点呢?我已经尝试了各种XML和JSON属性,但似乎无法使其工作。我还尝试使用 List<List<string>>
而不是 List<DataRow>
,它可以正确创建JSON,但XML 无法反序列化。
英文:
I have the following XML
<table>
<name>Table 1</name>
<headers>
<header>Header 1</header>
<header>Header 2</header>
</headers>
<data>
<row>
<row_item>Item 1</row_item>
<row_item>Item 2</row_item>
</row>
<row>
<row_item>Item 3</row_item>
<row_item>Item 4</row_item>
</row>
</data>
</table>
Now I can deserialize this easy enough using the built in XmlSerializer class using this class.
[JsonObject("table")]
[XmlRoot("table")]
public class Table
{
[JsonProperty("name")]
[XmlElement("name")]
public string Name { get; set; }
[JsonProperty("headers")]
[XmlArray("headers"), XmlArrayItem("header")]
public List<string> Headers { get; set; } = new List<string>();
[JsonProperty("data")]
[XmlArray("data"), XmlArrayItem("row")]
public List<DataRow> Data { get; set; } = new List<DataRow>();
}
public class DataRow
{
[XmlElement("row_item")]
public List<string> DataRowItems { get; set; }
}
Now I need to convert this to JSON, I am using Newtonsoft to do this but the problem I am facing is that the current class structure adds "DataRowItems" to the JSON.
{
"table": [
{
"data": [
{
"DataRowItems": [
"Item 1",
"Item 2"
]
},
{
"DataRowItems": [
"Item 3",
"Item 4"
]
}
],
"headers": [
"Item 1",
"Item 2",
"Item 3"
],
"name": "Some text"
}
]
}
Where as I need to send the data
element as an array of array, like this.
{
"table": [
{
"data": [
["Item 1", "Item 2", "Item 3"],
["Item 4", "Item 5", "Item 6"]
],
"headers": ["Column 1", "Column 2", "Column 3"],
"name": "Some text"
}
]
}
How can I achieve this? I have been trying with various XML and JSON attributes but can't seem to get it to work. I have also tried using List<List<string>> instead of List<DataRow> which creates the JSON correctly, but the XML fails to deseralize.
答案1
得分: 1
移除 DataRow 并以嵌套列表的方式进行如下操作:
{
"name":"aaa",
"headers":["H1","H2","H3"],
"data":[
["i1","i2"],
["i3","i4"]
]
}
英文:
Remove DataRow and put a nested List this way:
[JsonObject("table")]
[XmlRoot("table")]
public class Table
{
[JsonProperty("name")]
[XmlElement("name")]
public string Name { get; set; }
[JsonProperty("headers")]
[XmlArray("headers"), XmlArrayItem("header")]
public List<string> Headers { get; set; } = new List<string>();
[JsonProperty("data")]
[XmlArray("data"), XmlArrayItem("row")]
public List<List<string>> Data { get; set; } = new List<List<string>>();
}
I obtained:
{"name":"aaa","headers":["H1","H2","H3"],"data":[["i1","i2"],["i3","i4"]]}
答案2
得分: 1
以下是代码的翻译部分:
你可以尝试这个,你不需要任何自定义类
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);
var json = JsonConvert.SerializeXmlNode(xmlDoc, Newtonsoft.Json.Formatting.None, true);
var jObj = JObject.Parse(json);
jObj["headers"] = jObj["headers"]["header"];
jObj["data"] = new JArray(jObj["data"]["row"].Select(x => x["row_item"]));
json = jObj.ToString();
输出
{
"name": "Table 1",
"headers": [
"Header 1",
"Header 2"
],
"data": [
[
"Item 1",
"Item 2"
],
[
"Item 3",
"Item 4"
]
]
}
或者,如果你想要C#对象
DataClass data = jObj.ToObject<DataClass>();
public partial class DataClass
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("headers")]
public List<string> Headers { get; set; }
[JsonProperty("data")]
public List<List<string>> Data { get; set; }
}
英文:
you can try this, you don't need any custom classes
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);
var json = JsonConvert.SerializeXmlNode(xmlDoc, Newtonsoft.Json.Formatting.None, true);
var jObj = JObject.Parse(json);
jObj["headers"] = jObj["headers"]["header"];
jObj["data"] = new JArray(jObj["data"]["row"].Select(x => x["row_item"]));
json=jObj.ToString();
output
{
"name": "Table 1",
"headers": [
"Header 1",
"Header 2"
],
"data": [
[
"Item 1",
"Item 2"
],
[
"Item 3",
"Item 4"
]
]
}
or if you want c# object
DataClass data = jObj.ToObject<DataClass>();
public partial class DataClass
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("headers")]
public List<string> Headers { get; set; }
[JsonProperty("data")]
public List<List<string>> Data { get; set; }
}
</details>
# 答案3
**得分**: -1
谢谢大家的建议,这是我用来使其正常工作的类中属性的最终设置。
```csharp
[JsonProperty("data")]
[XmlArray("data")]
[XmlArrayItem("row")]
[XmlArrayItem("row_item", NestingLevel = 1)]
public List<List<string>> Data { get; set; } = new List<List<string>>();
```
`NestingLevel` 项是使 `row_item` 正确反序列化的关键。
<details>
<summary>英文:</summary>
Thank you everyone for the suggestions, this was the final setup for property in the class that I used to get it working.
[JsonProperty("data")]
[XmlArray("data")]
[XmlArrayItem("row")]
[XmlArrayItem("row_item", NestingLevel = 1)]
public List<List<string>> Data { get; set; } = new List<List<string>>();
The `NestingLevel` item was the key to getting `row_item` to deserialize correctly.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论