如何在 C# 中使用添加的自定义标签将 JSON 转换为 XML
Posted
技术标签:
【中文标题】如何在 C# 中使用添加的自定义标签将 JSON 转换为 XML【英文标题】:How to convert JSON to XML with added custom tag in C# 【发布时间】:2021-11-10 10:40:13 【问题描述】:我有一些这种格式的 JSON 示例:
"id": "532-513jg-5ujkl-5jiklf",
"externalGuid": "93804jlkfes",
"tagNumber": "2KMA",
"project":
"id": "532kg-fw13jg-553klal-5jiklf",
"projectName": "Test",
"projectId": "1"
,
"properties": [
"id": "jkl39-jkl39084-agd208-hh82a9",
"name": "Weight",
"value": "1000",
"statusCode":
"name": "Accepted",
"code": 1
,
"id": "jkl39-jkl384-123208-hh82a9",
"name": "Length",
"value": "10",
"statusCode":
"name": "Not Accepted",
"code": 3
]
我想将其转换为 XML,因此我执行以下操作:
XmlDocument node = JsonConvert.DeserializeXmlNode(jsonString, "tag");
这给了我以下 XML:
<tag>
<id>532-513jg-5ujkl-5jiklf</id>
<externalGuid>93804jlkfes</comosUID>
<tagNumber>2KMA</tagNumber>
<project>
<id>532kg-fw13jg-553klal-5jiklf</id>
<projectName>Test</projectName>
<projectId>1</projectId>
</project>
<properties>
<id>jkl39-jkl39084-agd208-hh82a9</id>
<name>Weight</name>
<value>1000</value>
<statusCode>
<name>Accepted</name>
<code>1</code>
</statusCode>
<properties>
<id>jkl39-jkl384-123208-hh82a9</id>
<name>Length</name>
<value>10</value>
<statusCode>
<name>Not Accepted</name>
<code>3</code>
</statusCode>
</properties>
</tag>
这几乎是我想要的。然而,将要导入 XML 的系统需要一种稍微不同的格式。它希望每个属性都以<property>
标记开始和结束。所以属性数组看起来像这样:
<properties>
<property>
<id>jkl39-jkl39084-agd208-hh82a9</id>
<name>Weight</name>
<value>1000</value>
<statusCode>
<name>Accepted</name>
<code>1</code>
</statusCode>
</property>
<property>
<id>jkl39-jkl384-123208-hh82a9</id>
<name>Length</name>
<value>10</value>
<statusCode>
<name>Not Accepted</name>
<code>3</code>
</statusCode>
</property>
</properties>
如何使 XML 匹配此模板?也就是说,将properties
标签替换为property
,并将所有property
标签包装在一个properties
父标签中。
【问题讨论】:
【参考方案1】:要更改输入格式,您应该首先将 JSON 反序列化为匹配模型,然后您可以使用 System.Xml.Linq 按您想要的顺序和结构导出节点。
Model model = JsonConvert.DeserializeObject<model>(jsonString);
var xml = new XElement("properties",
new XElement("property",
new XElement("id", model.Id),
new XElement("name", model.Name) /*and so on*/));
看起来要写很多东西,但实际上你可以用 XML 做任何你想做的事情。您可以准备方法来处理模型并对其进行调整,但这取决于您的要求。
您还可以创建另一个结构与 xml 文件对应的模型,然后您必须使用原始节点中的数据填充该模型,但这看起来像是很多不必要的工作。我个人会使用 System.Xml.Linq 来完成这样的任务。
【讨论】:
【参考方案2】:您可以编写一个自定义 XmlNodeConverter,如果当前元素是一个数组,它将插入一个父元素。例如,
public class ArrayXmlNodeConverter : XmlNodeConverter
public readonly string _arrayRootName;
public ArrayXmlNodeConverter(string rootElement,string arrayRootName)
(DeserializeRootElementName,_arrayRootName) = (rootElement,arrayRootName);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
var token = JObject.Load(reader);
ChangeArrayElementRoot(token);
reader = token.CreateReader();
reader.Read();
return base.ReadJson(reader, objectType, existingValue, serializer);
private void ChangeArrayElementRoot(JToken token)
if (token.Type == JTokenType.Array)
var arrayHolder = new JObject _arrayRootName, token ;
token.Replace(arrayHolder);
else
foreach (var childToken in token)
ChangeArrayElementRoot(childToken);
现在你可以使用 as
var xml = (XmlDocument)JsonConvert.DeserializeObject(jsonString,
typeof(XmlDocument),
new ArrayXmlNodeConverter("tag","Property"));
Demo Code
【讨论】:
【参考方案3】:这就是我解决它的方法。首先,我为相应的 JSON/XML 元素创建了 C# 类:
[XmlRoot("tag")]
[JsonObject(Title = "tag")]
public class Tag
[XmlElement("id")] public string Id get; set;
[XmlElement("externalGuid")] public string ExternalGuid get; set;
[XmlElement("tagNumber")] public string TagNumber get; set;
[XmlElement("project")] public Project Project get; set;
[XmlArray("properties")] public List<Property> Properties get; set;
[XmlType("property")]
public class Property
[XmlElement("id")] public string Id get; set;
[XmlElement("name")] public string Name get; set;
[XmlElement("value")] public string Value get; set;
[XmlElement("status")] public Status Status get; set;
public class Status
[XmlElement("id")] public string Id get; set;
[XmlElement("name")] public string Name get; set;
[XmlElement("code")] public int Code get; set;
public class Project
[XmlElement("id")] public string Id get; set;
[XmlElement("projectName")] public string ProjectName get; set;
[XmlElement("projectId")] public string ProjectId get; set;
然后我实现了一个自定义的 Json 到 XML 转换器:
public static string TransformJsonToXml<T>(string json)
var jsonObjectAttribute = typeof(T).GetCustomAttribute(typeof(JsonObjectAttribute)) as JsonObjectAttribute;
JObject root = JObject.Parse(json);
var data = root[jsonObjectAttribute.Title];
var obj = JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(data));
var serializer = new XmlSerializer(typeof(T));
var stringWriter = new StringWriter();
using var xmlWriter = XmlWriter.Create(stringWriter);
var xmlSerializerNamespaces = new XmlSerializerNamespaces();
xmlSerializerNamespaces.Add("","");
serializer.Serialize(xmlWriter, obj, xmlSerializerNamespaces);
return stringWriter.ToString();
现在将 JSON 转换为 XML 很简单:
var xml = TransformJsonToXml<Tag>(jsonInput);
【讨论】:
以上是关于如何在 C# 中使用添加的自定义标签将 JSON 转换为 XML的主要内容,如果未能解决你的问题,请参考以下文章
如何将多个键值条目的 JSON 对象反序列化为 Rust 中的自定义结构
我的 Joomla 模板正在使用 JS 加载我的自定义 CSS。有没有办法将唯一版本标签添加到我的自定义 CSS 中?即:custom.css?20180101