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
Related
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)
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
In VB.NET, is it possible to deserialize a JSON string to a dynamic / unknown datatype, then read the values from the object?
Dim js As New System.Web.Script.Serialization.JavaScriptSerializer()
Dim o As Object = js.DeserializeObject(json)
Dim s As String = String.Empty
For Each i As PropertyInfo In o.GetType().GetProperties()
s = String.Concat(s, i.Name) & "<br>"
Next
Response.Write(s)
It lists a bunch of things inside the object, but I can't seem to get to the value of these fields / properties.
I have the following code:
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Module Module1
Structure JSONList
Dim Name, Email As String
Dim Age As Integer
End Structure
Sub Main()
Dim Data(1) As JSONList
Data(0).Name = "Josh"
Data(0).Age = 17
Data(0).Email = "me#mail.co.uk"
Data(1).Name = "Greg"
Data(1).Age = 17
Data(1).Email = "greg#hotmail.co.uk"
Dim JSONEncode As String
JSONEncode = JsonConvert.SerializeObject(Data)
Console.WriteLine(JSONEncode)
Console.WriteLine()
Console.WriteLine()
Dim JSONDecode() As JSONList = JsonConvert.DeserializeObject(JSONEncode)
Console.WriteLine(JSONDecode(0).Name)
Console.ReadKey()
End Sub
End Module
The first encoding part of the script is used to store the encoded string to a database, the output is:
[{"Name":"Josh","Email":"me#mail.co.uk","Age":17},{"Name":"Greg","Email":"greg#hotmail.co.uk","Age":17}]
Now when I try to decode this JSON string, I get an error Unable to cast object of type 'Newtonsoft.Json.Linq.JArray' to type 'JSONList[]'.
I need the data to be encoded in the JSON format so that I can use it in my website that uses PHP to decode it. I am using Visual Basic 2010 along with JSON.NET.
The problem is that JsonConvert.DeserializeObject deserialises into an object of type Newtonsoft.Json.Linq.JArray which .net cannot automatically convert to an array of JSONList. A little bit of conversion is required:
Dim jsonObject As Newtonsoft.Json.Linq.JArray =
JsonConvert.DeserializeObject(JSONEncode)
Dim JSONDecode() As JSONList = (
From j In jsonObject
Select New JSONList() With {.Age = j("Age"),
.Email = j("Email"),
.Name = j("Name")}
).ToArray()
As #Adrian said, JsonConvert.DeserializeObject will deserialize to JArray, which .Net cannot automatically convert into an array of your JSONList structure. However, you don't need to do manual conversion; you simply need to use the overload of DeserializeObject which accepts a type parameter. This will allow Json.Net to deserialize directly to your type without needing any special conversion code.
Dim JSONDecode() As JSONList = _
JsonConvert.DeserializeObject(Of JSONList())(JSONEncode)
I have tried a few things like converting HTML to XML and then using an XML navigator to get input elements but I get lost whenever I start this process.
What I am trying to do is to navigate to a website which will be loaded using textbox1.text
Then download the html and parse out the input elements like . username, password, etc and place the element by type (id or name) into the richtextbox with the attribute beside the name.
Example.
Username id="username"
Password id="password"
Any clues or how to properly execute an HTML to XML conveter, reader, parser?
Thanks
It sounds like you just need a good HTML parsing library (instead of trying to use an XML parser). The HTML Agility Pack often fits this need. There are other options as well.
Somthing like below uses a streamreader to extract the source of the page into a string result
Dim uri As String = "https://www.yourUrl.com"
Dim request As HttpWebRequest = CType(WebRequest.Create(uri), HttpWebRequest)
Dim objRequest As HttpWebRequest = WebRequest.Create(uri)
Dim result As String
objRequest.Method = "GET"
Dim objResponse As HttpWebResponse = objRequest.GetResponse()
Dim sr As StreamReader
sr = New StreamReader(objResponse.GetResponseStream())
result = sr.ReadToEnd()
sr.Close
Then use regular expression (regex) to extra the attributes needed. for example something like this
Dim pattern As String = "(?<=Username id="")\w+"
Dim m0 As MatchCollection = Regex.Matches(result, pattern, RegexOptions.Singleline)
Dim m As Match
Dim k As Integer = 0
dim strUserID as String = ""
For Each m In m0
'extract the values for username id
strUserID = m0[k].Value;
k=k+1
Next
You'll need to change the pattern so it can pick up the other attributes you want to find, but this shouldn't be difficult