在Visual Basic中从JSON提取字符串数组

时间:2019-06-20 09:13:54

标签: arrays json vb.net json.net

我是Visual Basic中的新手。我正在从Web API下载一些数据。数据以JSON格式到达我。我的主要问题是,有时数据是一个字符串,有时则是一个字符串数组。在这里,您可以看到一个示例:

Texto = "{""1"":[""Trova Tutto""], 
          ""3"":""Tutta Sulla Tua Ricerca"",  
          ""4"":""Trova Qui"",  
          ""5"":[""https://www.smarter.com/it/ar?Trova+Tutto&q={keyword}"", ""delicious_potatoes""]}" 

我想知道该值何时是数组。如果是数组,我想提取每个值并将它们存储在返回变量(retorno

我试图从变量elemento.First中提取数据,但是我无法确定数据是数组还是字符串。我也尝试过反序列化,但是那也不起作用。

这是我的VB代码:

Public Shared Function getCustomParametersV2(texto As String) As Dictionary(Of String, Dictionary(Of String, String))
    Dim retorno As New Dictionary(Of String, Dictionary(Of String, String))
    Dim counter As New Integer
    Dim dict As Object
    Try
        If texto.Trim <> "--" Then
            Dim json As JObject = JObject.Parse(texto)
            For Each elemento In json.Children
                ' en el caso de que sea un array lo recorremos y unimos en un unico string
                'dict = JsonConvert.DeserializeObject(Of List(Of Object))(elemento.First)
                If IsArray(elemento.First) Then
                    counter = 0
                    For Each cosita In elemento.First
                        retorno.Add(elemento.Path, New Dictionary(Of String, String) From {{counter.ToString(), cosita}})
                        counter += 1
                    Next
                End If
                retorno.Add(elemento.Path, New Dictionary(Of String, String) From {{1, elemento.First}})
            Next
        End If
    Catch ex As Exception
        If Not retorno.ContainsKey("error") Then
            texto = texto.Replace("""", String.Empty)
            If texto.Length > 50 Then texto = texto.Substring(0, 50)
            retorno.Add("error", New Dictionary(Of String, String) From {{1, texto}})
        End If
    End Try

    Return retorno
End Function

我想提取之前显示的信息,但是我不知道如何创建信息,以便我的代码可以注意到何时是数组以及何时不是数组,并相应地提取值。

最后,我想提出以下意见:

retorno = {
           "1" : {"0": "Trova Tutto"}
           "3" : {"0": "Tutta Sulla Tua Ricerca"}
           "4" : {"0": "Trova Qui"}
           "5" : {"0": "https://www.smarter.com/it/ar?Trova+Tutto&q={keyword}"
           "5" : {"1": "delicious_potatoes" }
         }

1 个答案:

答案 0 :(得分:0)

首先说明您想要的结果。字典的键必须唯一,因此结果字典中实际上不能有两个5键。但是我注意到您的函数返回了Dictionary(Of String, Dictionary(Of String, String)),所以我认为您的实际意思是:

{
   "1": { "0": "Trova Tutto" }
   "3": { "0": "Tutta Sulla Tua Ricerca" }
   "4": { "0": "Trova Qui" }
   "5": {
          "0": "https://www.smarter.com/it/ar?Trova+Tutto&q={keyword}",
          "1": "delicious_potatoes"
        }
}

如果是这种情况,我们可以继续进行。

Children中的JObjectJProperties。您可以使用Children(Of T)泛型重载来确保将循环变量强制转换为正确的类型。每个JProperty都有一个Name和一个Value,后者是JToken的某种类型(在您的情况下,JValue代表一个字符串或一个JArray代表字符串数组)。要确定令牌是否为数组,可以检查其Type属性。如果类型为JTokenType.Array,则需要将所有数组值的 all 添加到内部字典中(而不是像现在那样将每个值添加到新字典中)。

代码应如下所示:

            Dim json As JObject = JObject.Parse(texto)
            For Each prop In json.Children(Of JProperty)()
                Dim innerDict As New Dictionary(Of String, String)
                If prop.Value.Type = JTokenType.Array Then
                    Dim counter As Integer = 0
                    For Each child In prop.Value.Children(Of JValue)
                        innerDict.Add(counter.ToString(), CStr(child))
                        counter += 1
                    Next
                Else
                    innerDict.Add("0", CStr(prop.Value))
                End If
                retorno.Add(prop.Name, innerDict)
            Next

这是一个有效的演示:https://dotnetfiddle.net/pQjhoy