我需要将传入的json文件转换为XML。
我使用以下代码来达到要求。我正在使用Newtonsoft Json Converter
XmlDocument doc = (XmlDocument)JsonConvert.DeserializeXmlNode(json);
输入文件是
{"menu": { "id": "file", "value": "File", "popup": { "menuitem": [ {"value": "New", "onclick": "CreateNewDoc()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"} ] }}}
我得到的输出是
<menu><id>file</id><value>File</value><popup><menuitem><value>New</value><onclick>CreateNewDoc()</onclick></menuitem><menuitem><value>Open</value><onclick>OpenDoc()</onclick></menuitem><menuitem><value>Close</value><onclick>CloseDoc()</onclick></menuitem></popup></menu>
所以这里的属性生成为节点。
先谢谢
答案 0 :(得分:2)
来自Converting between JSON and XML:
转换规则
- 属性以@为前缀,应位于对象的开头。
因此,您可以使用Linq to JSON使用原始值修改所有JSON属性,并在其名称前添加@
个字符。请注意,由于您的文件将是“以MB为单位”,因此您应该避免加载到临时字符串而是stream the file contents in directly:
// Load the JObject directly from a file
using (var streamReader = File.OpenText(fileName))
using (var jsonReader = new JsonTextReader(streamReader))
{
obj = JObject.Load(jsonReader);
}
// Rename all properties with primitive values (string, number, boolean, null) to begin with "@"
foreach (var o in obj.Descendants().OfType<JObject>())
{
// Attributes must appear first in the JObject's property list.
int insertIndex = 0;
foreach (var property in o.Properties().Where((p => p.Value is JValue && !p.Name.StartsWith("@"))).ToList())
{
property.Remove();
((IList<JToken>)o).Insert(insertIndex++, new JProperty("@" + property.Name, property.Value));
}
}
// Convert to XmlDocument
XmlDocument doc;
using (var reader = obj.CreateReader())
{
doc = (XmlDocument)JsonExtensions.DeserializeXmlNode(reader);
}
使用辅助方法:
public static class JsonExtensions
{
public static XmlDocument DeserializeXmlNode(JsonReader reader)
{
return DeserializeXmlNode(reader, null, false);
}
public static XmlDocument DeserializeXmlNode(JsonReader reader, string deserializeRootElementName, bool writeArrayAttribute)
{
var converter = new Newtonsoft.Json.Converters.XmlNodeConverter() { DeserializeRootElementName = deserializeRootElementName, WriteArrayAttribute = writeArrayAttribute };
var jsonSerializer = JsonSerializer.CreateDefault(new JsonSerializerSettings { Converters = new JsonConverter[] { converter } });
return (XmlDocument)jsonSerializer.Deserialize(reader, typeof(XmlDocument));
}
}
这会产生输出:
<menu id="file" value="File"> <popup> <menuitem value="New" onclick="CreateNewDoc()" /> <menuitem value="Open" onclick="OpenDoc()" /> <menuitem value="Close" onclick="CloseDoc()" /> </popup> </menu>
答案 1 :(得分:0)
您应该在属性名称之前附加@
。
像这样:
{"menu": { "@id": "file", "@value": "File", "popup": { "menuitem": [ {"@value": "New", "@onclick": "CreateNewDoc()"}, {"@value": "Open", "@onclick": "OpenDoc()"}, {"@value": "Close", "@onclick": "CloseDoc()"} ] }}}
这将创建以下XML:
<menu id="file" value="File">
<popup>
<menuitem value="New" onclick="CreateNewDoc()" />
<menuitem value="Open" onclick="OpenDoc()" />
<menuitem value="Close" onclick="CloseDoc()" />
</popup>
</menu>
如果您无法控制JSON,那么您可以在转换为XML之前对其进行编程修改,如下所示:
json = json.Replace("id", "@id").Replace("value", "@value").Replace("onclick", "@onclick");
或者您可以使用XSLT转换后转换XML。