I have following xml string format where property key is random and not known but always start with alphanumeric character
<properties>
<property key="EventId">3300</property>
<property key="source">car</property>
<property key="type">omega</property>
<property key="a341414">any value</property>
<property key="arandomstring_each_time_different">any value</property>
....
</properties>
how to achieve following format
{
"properties":
{
"EventId": "3300",
"source": "car",
...
}
}
I tried some variation of following code, but with no luck
XDocument doc = XDocument.Parse(string);
string jsonText = JsonConvert.SerializeXNode(doc);
var dynamic = JsonConvert.DeserializeObject<ExpandoObject>(jsonText);
output
{
"properties":{
"property":[
{
"@key":"EventId",
"#text":"3300"
},
{
"@key":"source",
"#text":"car"
},
...
]
}
}
If you want to purely rely on Json.Net then you can do that as well:
var docInXml = XDocument.Parse("...");
var docInJson = JsonConvert.SerializeXNode(docInXml);
var semiParsedJson = JObject.Parse(docInJson);
var propertyCollection = semiParsedJson["properties"]["property"] as JArray;
var keyValueMapping = new Dictionary<string, string>();
foreach(var item in propertyCollection.Children())
{
keyValueMapping.Add((string)item["@key"], (string)item["#text"]);
}
var result = new JObject(new JProperty("properties", JObject.FromObject(keyValueMapping)));
Let's see the code line-by-line:
var docInXml = XDocument.Parse("...");
XDocument
var docInJson = JsonConvert.SerializeXNode(docInXml);
XDocument
to json{
"properties":{
"property":[
{
"@key":"EventId",
"#text":"3300"
},
{
"@key":"source",
"#text":"car"
},
{
"@key":"type",
"#text":"omega"
},
{
"@key":"a341414",
"#text":"any value"
},
{
"@key":"arandomstring_each_time_different",
"#text":"any value"
}
]
}
}
var semiParsedJson = JObject.Parse(docInJson);
var propertyCollection = semiParsedJson["properties"]["property"] as JArray;
property
collection as an arrayvar keyValueMapping = new Dictionary<string, string>();
foreach(var item in propertyCollection.Children())
keyValueMapping.Add((string)item["@key"], (string)item["#text"]);
JObject
to string
JObject.FromObject(keyValueMapping)))
Dictionary
into a JObject
{
"EventId": "3300",
"source": "car",
"type": "omega",
"a341414": "any value",
"arandomstring_each_time_different": "any value"
}
var result = new JObject(new JProperty("properties", ...));
JObject
{
"properties": {
"EventId": "3300",
"source": "car",
"type": "omega",
"a341414": "any value",
"arandomstring_each_time_different": "any value"
}
}
Json.NET is behaving as documented in Converting between JSON and XML :
Single child text nodes are a value directly against an element, otherwise they are accessed via #text.
Since your <property>
nodes have an attribute, the value is placed into in a #text
property.
But why use Json.NET to convert from XElement
to ExpandoObject
? It's simple enough to do the conversion directly using LINQ to XML:
var doc = XDocument.Parse(xml);
IDictionary<string, object> properties = new ExpandoObject();
foreach (var property in doc.Root.Elements("property"))
properties.Add(property.Attribute("key").Value, property.Value);
dynamic d = new ExpandoObject();
d.properties = properties;
Which results in, as required:
{
"properties": {
"EventId": "3300",
"source": "car",
"type": "omega",
"a341414": "any value",
"arandomstring_each_time_different": "any value"
}
}
Demo fiddle here .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.