What I am trying to achieve is convert XML to a JSON object. Currently I am doing it like this:
Public Class Person
Public Property Name As String
' other properties here'
End Class
Dim doc As XmlDocument
doc.LoadXml(arg_strXml)
Dim jsonValue As String = JsonConvert.SerializeXmlNode(doc)
Dim jsonObject = JsonConvert.DeserializeObject(Of Person)(jsonValue)
Dim firstName As String = jsonObject.Name
However the issue is the retrieved XML, and thus the deserialized JSON object has different fields/properties/elements depending on the correct function. It would be a nightmare to have a class for each possible XML.
Is there a way round not having to create a specific class (Person in this case) for each deserialize?
You can deserialze/parse your JSON string into Newtonsoft's JObject. Then you can access the properties like Dictionary(Of String, String), for example :
Dim arg_strXml = "<Person><Name>foo</Name></Person>"
Dim doc = New XmlDocument()
doc.LoadXml(arg_strXml)
Dim jsonValue = JsonConvert.SerializeXmlNode(doc)
Dim jsonObject = JObject.Parse(jsonValue)
Console.WriteLine(jsonObject("Person")("Name"))
dotnetfiddle demo
output :
foo
Related
I am trying to deserialize this object from json to string but it doesnt work.
[\"661253BF9FE5463D968AC4CF9179FC56\"] -- this is the object.
Dim idDes As String = JsonConvert.DeserializeObject(id)
I want it like this: "661253BF9FE5463D968AC4CF9179FC56"
Any help?
What your JSON is telling you is that it's an array of strings, that's what you need to deserialize and if you always know you want the first string in that array you can access like this:
Dim idDes As String
Dim arr As String() = JsonConvert.DeserializeObject(Of String())(json)
idDes = arr.First()
I have a problem deserializing the following JSON string:
{"error":null,"id":1234,"result":[[["config.param1","111"],["config.param2","1222"]],"Config System",1234]}
My structure is:
Public Structure stuConResponse
Dim [Error] As String
Dim ID As String
Dim Result As List(Of stuSubResults)
End Structure
Public Structure stuSubResults
Public Property X1 As List(Of List(Of String))
Public Property X2 As String
Public Property X3 As String
End Structure
And my code is:
Dim JSonSettings As New Newtonsoft.Json.JsonSerializerSettings
JSonSettings.CheckAdditionalContent = True
JSonSettings.DateParseHandling = Newtonsoft.Json.DateParseHandling.DateTime
JSonSettings.DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.Ignore
JSonSettings.FloatFormatHandling = Newtonsoft.Json.FloatFormatHandling.DefaultValue
JSonSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore
Dim HeloResponse As Structures.stuConResponse = Newtonsoft.Json.JsonConvert.DeserializeObject(Of Structures.stuConResponse)(ReceivedData, JSonSettings)
I tried making "Results" the following:
1) A tuple of (list of (list of (string), string, string))
2) A list of (list of (string))
3) Other lists and tuples combined
For the life of me, I can't deserialise the "result" object whatsoever.
I have no problems reading the error and ID, but when Result comes in, I get the error that JSON can't do it.
I don't also mind if "result" can go into a string un-deserialised where I can do some manual logic, but that also don't work as JSON is trying to be too cleaver.
In other words, the problem is getting JSON to read "[[[X1,Y1],[X2,Y2],X3,X4]", notice that it's a list/array and that it does not have any Key-names which is where the problem is (I think).
It would be great to get your thoughts on this one.
Thanks
Dim JSONC = New JavaScriptSerializer().DeserializeObject(yourjson)
Debug.Print(JSONC("result")(0)(0)(0)) 'get result collection, then first element, then first object then first element of object
You decide what you want to do with the object.
You can convert ii to dictionary then get stuff with ("key") but if the data stays the same I see no point.
Finally, I solved it!, I had no idea that you can use IDICTIONARY to read the whole thing and then break it down into ILISTs...
For anyone who is having the same problem, here is the solution:
1) Code:
Dim I As Integer
Dim ConPolConfig As Structures.stuConPolSubscribeResponse = Nothing
Dim dicItems As IDictionary = Newtonsoft.Json.JsonConvert.DeserializeObject(Of IDictionary)(ReceivedData, JSonSettings)
ConPolConfig.ID = dicItems("id")
ConPolConfig.Error = dicItems("error")
If Not dicItems("result") Is Nothing Then
ConPolConfig.ConfigItems = New List(Of Dictionary(Of String, String))
Dim ConfigProperties As IList = dicItems("result")(0)
Dim ConfSysReader As String = dicItems("result")(1)
Dim Token As Integer = dicItems("result")(2)
Dim ParamKey As String
Dim ParamVal As String
Dim Dic As New Dictionary(Of String, String)
For I = 0 To ConfigProperties.Count - 1
ParamKey = ConfigProperties(I)(0)
ParamVal = ConfigProperties(I)(1)
Dic.Add(ParamKey, ParamVal)
ConPolConfig.ConfigItems.Add(Dic)
Next
End If
2) Structures:
Public Structure stuConPolSubscribeResponse
Dim [Error] As String
Dim ID As String
Dim ConfigItems As List(Of Dictionary(Of String, String))
End Structure
This works and does exactly what I am looking for as per my initial question. i.e. reading a list or lists where the master list has an additional 2 different elements (a string and an integer). the iDictionary would read the whole thing without any errors and then you could iterate it using an ILIST...
Don't ask me why the source JSON string is written in such a way... but now this works to read it...
... I need a coffee ...
How can I get the name of a key in a json file? I have a json that I'm parsing in VB.NET and one of the 'fields' have a dynamic name (it changes). What could I do to get the key name?
For example:
...
"one":{
"two":{
"example":[
{
"aaa":"test",
"bbb":"test",
"ccc":"test"
},
...
I'm getting correctly all the values (test, test, test...) and the keys 'one', 'two', have always the same name. But the key 'example' changes the name according the json file information. How could I identify the key text?
I wrote a piece of code that converts JSON into a XDocument here: https://github.com/dday9/.NET-JSON-Transformer
If you were to use that code, then you could get the node that represents your "two" object and then get the first child node in to. By doing this, you're essentially getting the array by an Index instead of by a name.
Here is a quick example of what I mean:
Dim literal As String = "{""two"":{""example"":[{""aaa"":""test"",""bbb"":""test"",""ccc"":""test""}]}}"
Dim xJSON As XDocument = JSON.Parse(literal)
Dim object_two As XElement = xJSON.Descendants("two").FirstOrDefault()
If object_two IsNot Nothing Then
Dim first_descendent As XElement = object_two.Descendants().Skip(1).FirstOrDefault()
If first_descendent IsNot Nothing Then
Console.WriteLine(first_descendent)
End If
End If
Fiddle: Live Demo
This piece will allow to get data from an unknown JSON structure, without having to define a class.
Sample
Dim serializer As System.Web.Script.Serialization.JavaScriptSerializer
serializer = New JavaScriptSerializer()
' {"elements":[{"handle~":{"emailAddress":"myself#example.com"},"handle":"urn:li:emailAddress:348955221"}]}
dim json as string
Dim obj As System.Collections.Generic.IDictionary(Of String, Object)
obj = serializer.Deserialize(Of System.Collections.Generic.IDictionary(Of String, Object))(json)
dim email as string=string.empty
email = If(GetJsonValue(obj, {"elements", "handle~", "emailAddress"}.ToList()), email)
The Function, very self descriptive:
''' <summary>decode json data </summary>
Public Function GetJsonValue(ByVal obj As Object,
ByVal key As List(Of String)) As String
GetJsonValue = Nothing
' If the object is an array, assume any element can contain the key
If obj.GetType Is GetType(Object()) Then
For Each newObj As Object In CType(obj, Object())
Dim tmp As String = GetJsonValue(newObj, key)
If Not String.IsNullOrEmpty(tmp) Then Return tmp
Next
Else
Dim objEle As System.Collections.Generic.IDictionary(Of String, Object)
Dim keyName As String
Dim objKey As String
'
keyName = key(0)
objEle = CType(obj, System.Collections.Generic.IDictionary(Of String, Object))
objKey = objEle.Keys.ToArray()(0)
If objEle.ContainsKey(keyName) Then
Dim temp As Object = objEle.Item(keyName)
If key.Count > 1 Then
' if the element is array, we need to get the array element and move to the next
key.RemoveAt(0)
Return GetJsonValue(temp, key)
Else
Return temp.ToString()
End If
End If
End If
End Function
I see this is solved but would like to suggest another solution for future readers. The JavaScriptSerializer can return a nested dictionary collection (Of String, Object). I find it easier to explore the result in debug while coding. The code below shows an example of how to navigate the collections.
Dim deserializer As New System.Web.Script.Serialization.JavaScriptSerializer
Dim text As String = "{""two"":{""example"":[{""aaa"":""test"",""bbb"":""test"",""ccc"":""test""}]}}"
Dim dict As Dictionary(Of String, Object) = deserializer.DeserializeObject(text)
Dim keys As Dictionary(Of String, Object).KeyCollection
keys = dict("two")("example")(0).Keys
Dim aaaName As String = keys(0)
Dim aaaValue As String = dict("two")("example")(0)(aaaName)
This is the json data I am trying to parse. (I did trim the imagedata down for example purposes)
{"imageData":["SUkqAORlAACGniG0JCHeSTV9icwWxF+N9AwzcsTDlLu+PeYCgeZXAP//","sfsdfsdyfhh2h43h8ysdfsdnvjknjfdsfdsf"]}
Any idea on how to parse it into a strongly typed class in .NET?
I am using the newtonsoft.json
I tried the following
Public Class DAFGImages
Public imageData As List(Of String)
End Class
Dim DAFGImages As List(Of DAFGImages) = Newtonsoft.Json.JsonConvert.DeserializeObject(json, GetType(List(Of DAFGImages)))
Your class already contains a List of string, so you dont need a list of DAFGImages too. I would change the class member to a property:
Public Class DAFGImages
Public Property imageData As List(Of String)
End Class
Then:
Dim jstr = ... from wherever
Dim myImgs = Newtonsoft.Json.JsonConvert.DeserializeObject(Of DAFGImages)(jstr)
myImgs.ImageData will contain the 2 elements.
I convert XML to JSON like so:
Dim doc As XmlDocument
doc.LoadXml(arg_strXml)
Dim jsonObject As String = JsonConvert.SerializeXmlNode(doc)
Now I would like to be able to go into jsonObject to get values, like so
Dim mode As String = jsobObject.mode
Or more advanced example
Dim usersFirstName As String = jsonObject.people[1].firstname
Do I need to create a class which represents the XML structure or can I do it another way, even if I lose the intellisense, like so
Dim mode As String = jsonObject["mode"]
Seems like you first conversion was unnecessary,
you can access all values you need from xml with LINQ to XML and feature of vb.net XML Literals
Dim xmlString as String = "
<someobject>
<property1>Value 1</property1>
<property2>1001</property2>
</someobject>"
Dim xmlObject As XElement = XElement.Parse(xmlString)
Dim value1 As String = xmlObject.<property1>.First().Value
Dim value2 As String = xmlObject.<property2>.First().Value