Take specific value from a JSON or XML

Asked

Viewed 1,546 times

5

Hello, I have an entire JSON inside a string and I need to turn it into an object in order to access some data... I’ll leave the code below to see if you can help me.

My JSON is in that string:

string json = Newtonsoft.Json.JsonConvert.SerializeXmlNode(doc);

part of the JSON:

{
"?xml":{"@version":"1.0","@encoding":"Windows-1252","@standalone":"yes"},
  "VFPData": {
    "row": [
      {
        "@numero": "000",
        "@descricao": "Menu principal",
      },
      {
        "@numero": "001",
        "@descricao": "Arquivos",
      }
    ]
  }
}

I need to access the values of these @descrição.

I’m using .Net Core Razor Pages... someone there could give me a hand with this ???

JSON(JSON Visualize from VS):

inserir a descrição da imagem aqui

the @descricao is the @des_mn0, that I need to take.

AS I AM DOING:

public class DadosMenu
{
    [JsonProperty("VFPData")]
    public VFP vfp { get; set; }
}
public class VFP
{
    [JsonProperty("row")]
    public Row[] row { get; set; }
}
public class Row
{
    [JsonProperty("@des_mn0")]
    public string des { get; set; }
}

(public IActionResult OnGet(){}):

var xml = System.IO.File.ReadAllText(@"C:\Dados\VS\MenuXML\menuV11.Xml");

XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string json = JsonConvert.SerializeXmlNode(doc).ToString();

DadosMenu result = JsonConvert.DeserializeObject<DadosMenu>(json);

for (int i = 1; i < 9; i++)
{
    descr +=  result.vfp.row[i].des + " - ";
}
HttpContext.Session.SetString("xmltojson", descr);

EDIT: Okay, I’m already getting the values I need... thank you all for the answers, and I’ve updated the question, showing how I’m doing to get the values.

If possible, if you can do the same (take a specific value) in an XML, it will save me a little work... then I will leave part of the XML below, so you can know how to do...

OBS:

1 - XML refers to the same json subject. I just transformed it.

2 - I need to save this data I took, in a lista, so that I can then use them to assemble a menu.(nav-bar)

(XML)

<?xml version = "1.0" encoding="Windows-1252" standalone="yes"?>
<VFPData>
    <xsd:schema id="VFPData" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
        <xsd:element name="VFPData" msdata:IsDataSet="true">
            <xsd:complexType>
                <xsd:choice maxOccurs="unbounded">
                    <xsd:element name="row" minOccurs="0" maxOccurs="unbounded">
                        <xsd:complexType>
                            <xsd:attribute name="num_mn0" use="required">
                                <xsd:simpleType>
                                    <xsd:restriction base="xsd:string">
                                        <xsd:maxLength value="15"/>
                                    </xsd:restriction>
                                </xsd:simpleType>
                            </xsd:attribute>
                            <xsd:attribute name="des_mn0" use="required">
                                <xsd:simpleType>
                                    <xsd:restriction base="xsd:string">
                                        <xsd:maxLength value="200"/>
                                    </xsd:restriction>
                                </xsd:simpleType>
                            </xsd:attribute>
                        </xsd:complexType>
                    </xsd:element>
                </xsd:choice>
                <xsd:anyAttribute namespace="http://www.w3.org/XML/1998/namespace" processContents="lax"/>
            </xsd:complexType>
        </xsd:element>
    </xsd:schema>
<row num_mn0="000" des_mn0="Menu principal"/>
<row num_mn0="001" des_mn0="Arquivos"/>

I need to get the value of des_mn0.

EDIT2:

error that appears when trying to answer Alisson:

inserir a descrição da imagem aqui

Onget:

XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string json = JsonConvert.SerializeXmlNode(doc);

DadosMenu result = JsonConvert.DeserializeObject<DadosMenu>(json);

ViewData["DadosMenu"] = result.vfp.row;

return Page();

I had, yesterday, created a list that I keep all the information I need... I just don’t know how to get this data in HTML, look how I did:

XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string json = JsonConvert.SerializeXmlNode(doc);

DadosMenu result = JsonConvert.DeserializeObject<DadosMenu>(json);

List<string> MenuPrincipal = new List<string>();
int i = 1;
while (result.vfp.row[i].men != "")
{
    if (result.vfp.row[i].men == "_MSYSMENU")
    {
        MenuPrincipal.Add(result.vfp.row[i].des);
    }
    else
    {
        break;
    }
    i++;
}

ViewData["MenuPrincipal"] = MenuPrincipal;

return Page();
  • The data you receive is json itself?

  • is yes @Virgilionovic... I’m actually getting in xml and turn to json, as the code shows

  • 1

    if you are receiving in XML it was not better to do for it?

  • @Virgilionovic, if you have any idea how to do it, you can leave it in the answers... but I tried it the way Alisson commented, but it didn’t work out... if you want, tell me that I leave part of the xml in the question.

  • Samuel I made a version with Json, if put the XML later I do with it also just post the question and adapt to that because you asked with JSON.

  • quiet... in about 30 Minutes I make the changes for you @Virgilionovic

  • I think it’s fitting @Virgilionovic

  • @Samuelmumbered by what I saw in the code you have now, with the code you already have, change in your VFP class the Row[] by List<Row>. Then in your result you will already have the list ready, just use result.vfp.Row to access.

  • I’ll take the test, but thanks for the @Alissonmarqui tip. So I should exchange, within my VFP class, the public Row[] row { get; set; } for public List<Row> row { get; set; }?

  • @Samuelmed this, by making this switch the Row property of the VFP class will be a list of the Row object, and Jsonconvert already Convert the JSON in List.

  • @Samuelmachado If I understand, you want to put this on a list to return to your View as Model, right ? if it is I edit my reply leaving more complete...

  • @Alissonmarqui, I need to take the values returned (one by one), to assemble my menu, through these returns, which for now will have the options "Main Menu" and "Archives"

  • Great @Alissonmarqui... I’ll take the test, thank you very much

  • I tried what you said @Alissonmarqui, and it was really great, but I need to create a new list, with every data of my for... Then each item he adds will be added a new item to the new object list

  • @Samuelmachado you are already with a list and are doing go on her, her List is the current Row object, you want to generate a List of what? I don’t understand why you need to generate a new List...

  • I did the editing with XML

  • @Samuelmachado edited the answer exemplifying the generation of Nav-bar, according to what I understood from his Dit and the comments.

Show 12 more comments

4 answers

5


Convert JSON

To convert JSON to object using the public Json.NET your model must follow the same structure as your JSON so that the component can convert. Classes and properties have to respect JSON names so you can use the annotation JsonProperty.

In your JSON you have a Vfpdata object with an array of Row object, which contains the data, so your model would be as follows:

Model:

public class DadosMenu
{
    [JsonProperty("VFPData")]
    public VFP vfp { get; set; }
}

public class VFP
{
    [JsonProperty("row")]
    public List<Row> row { get; set; }
}

public class Row
{
    [JsonProperty("@des_mn0")]
    public string des { get; set; }
}

With the model created according to JSON Deserializeobject will be able to populate the object correctly.


View

As you mentioned on the issue’s Edit and in the comments, you need this data to mount the nav-bar from the menu in your view.

Now with the data populated in the objects, you can in your controller return the list in several ways, I believe the two most common is by Viewdata and by model in strongly typed view.

Having this data in View either by Viewdata or Model you can do the for and generate your Nav-bar directly on Razor.

Note: The two examples will be in the code, just remove what you will not use.

Example:

Controller

public IActionResult OnGet(){
    var xml = System.IO.File.ReadAllText(@"C:\Dados\VS\MenuXML\menuV11.Xml");

    XmlDocument doc = new XmlDocument();
    doc.LoadXml(xml);
    string json = JsonConvert.SerializeXmlNode(doc).ToString();

    DadosMenu result = JsonConvert.DeserializeObject<DadosMenu>(json);

    // Caso queira retornar por ViewData utilize esta linha abaixo
    ViewData["DadosMenu"] = result.vfp.row; 

    // Nesta linha retornara para a View e ela deve ser anotada com 
    // @model ObjetoModelDaView
    return View(result.vfp.row);
}

View

// Usar essa linha se optar por Fortemente Tipada
// Esta linha é quem define o tipo da View
// Tem que ser o mesmo tipo que voce vai retornar no controller em return View(objeto)
@model List<Row>

<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <a class="navbar-brand" href="#">Navbar</a>
  <div class="collapse navbar-collapse" id="navbarNav">
    <ul class="navbar-nav">
      @{
        // Usar se optar por ViewData    
        var rows = ViewData.DadosMenu as List<Row>; 

        // Se for usar Fortemente Tipada trocar rows por Model
        // Pois o Model da view é a List<Row>
        for (Row row : rows) {
          <li class="nav-item">
            <a class="nav-link" href="#">@row.des</a>
          </li>
        }
      }          
    </ul>
  </div>
</nav>
  • Great... very good answer, just one more question, if possible... I need to put together a list of these values... I know it’s a silly question, but I’m starting my studies now, so I need a little help

  • @Samuelmachado if my answer helped you with the problem in question mark as correct please. As for the other doubt in the comment above, you want to create a page listing this data in an html table ?

  • not in a table... I need to take the values and save in a List<>, to then use them to build a menu, according to their values... I was able to take the values in another way, and using a for() to get them all, and you’re getting everyone I really need, but I don’t know how to store in a list

  • @Samuelmachado create a question with this doubt of the list, and put there like this your code, send the link here and enter the answer, it is easier, in the comments is difficult. And as to that question, if my answer helped you mark it as accepted, thank you.

  • all right, thanks

  • I believe there are some errors, as for example the use of the Viewdata... would not be, in case, ViewData["DadosMenu"] instead of ViewData.DadosMenu? And it also made some mistakes, I tried to get it back to me without being on a menu, just to check the values, and it didn’t work, I’ll leave a print on the question, like EDIT2 for you to take a look.

  • and as to the return View(parametro), also did not work... I am currently using a return Page(); and from what I read, it doesn’t accept parameters.

  • @Samuelmfound in the ASP has the Viewdata and Viewbag I wrote the way you use the Viewbag using the Viewdata. the Viewdata is ViewData["DadosMenu"] and Viewbag is ViewBag.DadosMenu. I edited the question correcting the error, Viewdata needs Typecasting when retrieving the information to know which object is coming in it.

  • Alisson, thank you so much for your reply... I modified some things to make it work... but it was you who gave me the basis, thank you very much

  • 1

    @I’m glad I helped! Last tip, you starting with Asp.net see the contents of Eduardo Pires he has great contents.

Show 5 more comments

5

I suggest you use the library Json.net that can be downloaded here.

Then it’s just:

using Newtonsoft.Json;

...
var result = JsonConvert.DeserializeObject<teste>(json);

Where the teste corresponds to the object type that corresponds to the string of your Json.

  • even with your hint, I’m not getting to do with that json I left example... I could make an example that works with that json?

  • I’ll leave a print of how my json is, according to VS JSON Visualizer.

3

Edited the question and closing that XML that came wrong stands as an example:

XML:

<?xml version = "1.0" encoding="Windows-1252" standalone="yes"?>
<VFPData>
    <xsd:schema id="VFPData" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
        <xsd:element name="VFPData" msdata:IsDataSet="true">
            <xsd:complexType>
                <xsd:choice maxOccurs="unbounded">
                    <xsd:element name="row" minOccurs="0" maxOccurs="unbounded">
                        <xsd:complexType>
                            <xsd:attribute name="num_mn0" use="required">
                                <xsd:simpleType>
                                    <xsd:restriction base="xsd:string">
                                        <xsd:maxLength value="15"/>
                                    </xsd:restriction>
                                </xsd:simpleType>
                            </xsd:attribute>
                            <xsd:attribute name="des_mn0" use="required">
                                <xsd:simpleType>
                                    <xsd:restriction base="xsd:string">
                                        <xsd:maxLength value="200"/>
                                    </xsd:restriction>
                                </xsd:simpleType>
                            </xsd:attribute>
                        </xsd:complexType>
                    </xsd:element>
                </xsd:choice>
                <xsd:anyAttribute namespace="http://www.w3.org/XML/1998/namespace" processContents="lax"/>
            </xsd:complexType>
        </xsd:element>
    </xsd:schema>
    <row num_mn0="000" des_mn0="Menu principal"/>
    <row num_mn0="001" des_mn0="Arquivos"/>
<VFPData/>

Classes:

using System;
using System.ComponentModel;
using System.Xml.Serialization;

[Serializable()]
[DesignerCategory("code")]
[XmlType(AnonymousType = true)]
[XmlRoot(Namespace = "", IsNullable = false)]
public partial class VFPData
{
    [XmlElement("row")]
    public VFPDataRow[] Rows { get; set; }
}

[Serializable()]
[DesignerCategory("code")]
[XmlType(AnonymousType = true)]
public partial class VFPDataRow
{     
    [XmlAttribute("num_mn0")]
    public string Number { get; set; }        
    [XmlAttribute("des_mn0")]
    public string Description { get; set; }
}

Code creating a typed data with this information:

var serializer = new XmlSerializer(typeof(VFPData));
using (var textReader = new StreamReader("./data.xml"))
{
    VFPData data = (VFPData)serializer.Deserialize(textReader);
}

JSON:

Basically modeling for classes and with the package Json.NET configuring Jsonproperty, example:

public class Rootobject
{
    [JsonProperty("?xml")]
    public Xml Xml { get; set; }
    [JsonProperty("VFPData")]
    public Vfpdata Vfpdata { get; set; }
}

public class Xml
{
    [JsonProperty("@version")]
    public string Version { get; set; }
    [JsonProperty("@encoding")]
    public string Encoding { get; set; }
    [JsonProperty("@standalone")]
    public string Standalone { get; set; }
}

public class Vfpdata
{
    [JsonProperty("row")]
    public Row[] Rows { get; set; }
}

public class Row
{
    [JsonProperty("@numero")]
    public string Numero { get; set; }
    [JsonProperty("@descricao")]
    public string Descricao { get; set; }
}

and carrying the json:

var json = System.IO.File.ReadAllText("./data.json");
Rootobject root = JsonConvert.DeserializeObject<Rootobject>(json);

Ref. Documentation - Json.NET

0

1- You are using the Dados as an object of deserialization:

Dados result = JsonConvert.DeserializeObject<Dados>(json);

But the object to which the string json refers is the DadosMenu

2- You are trying to get the property @des_mn0 but the example JSON has the property @descricao

  • I put in question... the @descricao is the @des_mn0, that I need to take.

  • Yes, but why are you using Jsonproperty @des_mn0 if in JSON is @descricao?

  • 1

    I modified the json to post... what I meant is that the @descricao is the same thing as the @des_mn0... It’s like Spider-Man and Peter Parker, you know,?

  • Got it. But wouldn’t it be better to leave it exactly as it is in the code? I say why it influences the sonConvert.DeserializeObject()

Browser other questions tagged

You are not signed in. Login or sign up in order to post.