read XML file to create a 3D model - c#

I have to load the Data from XML (custom but its based on XML file format (URF-8)) and use them to create model in Unity. I used XmlSerializer class, custom creation and tried all XML helps in forums, etc..
I debugged everything (step by step) and everything works fine but after that i always have problem with container. (i have error with reading)
Please, if you have any experince with this, can you tell me what method can be useful for this? ty
XML struct file
here is my try for XMLserializer: (some discriptions of tags XML are commented (tried everything :D)
//load.cs - creating a container
using System;
using System.Xml;
using System.Xml.Serialization;
using System.Collections.Generic;
using UnityEngine;
public class Load
{
//[XmlAttribute("block type")]
public float x_position;
public float y_position;
public float z_position;
}
//[XmlRoot("model version")]
public class Container
{
//[XmlArrayItem("block type")]
public List<Load> Load_container = new List<Load>();
}
//loadFile is main program.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
public class LoadFile: MonoBehaviour
{
public string path;
// Start is called before the first frame update
void Start()
{
var serializer = new XmlSerializer(typeof(Container));
var stream = new FileStream(path, FileMode.Open);
var container_load = serializer.Deserialize(stream) as Container;
stream.Close();
//Debug.Log();
}
// Update is called once per frame
void Update()
{
}
}

Try following :
[XmlRoot("model")]
public class Model
{
[XmlAttribute()]
public string version { get; set; }
[XmlElement("block")]
List<Block> block { get; set; }
}
public class Block
{
[XmlAttribute()]
public string type { get; set; }
public float x_position { get; set; }
public float y_position { get; set; }
public float z_position { get; set; }
}

Related

Get List from JSON [duplicate]

This question already has answers here:
Parse JSON response where the object starts with a number in c#
(2 answers)
Closed 1 year ago.
I am trying to get the List from a JSON string from a 3rd party API.
I am not able to understand how should I parse it,as the key name starts with numeric.
I do not need the key but I do require value, but I require the value part in my code to be stored in DB.
JSON
{
"5MIN": [
{
"SETTLEMENTDATE": "2021-08-16T00:30:00",
"REGIONID": "NSW1",
"REGION": "NSW1",
"RRP": 39.27,
"TOTALDEMAND": 7416.02,
"PERIODTYPE": "ACTUAL",
"NETINTERCHANGE": -788.69,
"SCHEDULEDGENERATION": 5518.17,
"SEMISCHEDULEDGENERATION": 1076.47
},
{
"SETTLEMENTDATE": "2021-08-16T01:00:00",
"REGIONID": "NSW1",
"REGION": "NSW1",
"RRP": 36.51,
"TOTALDEMAND": 7288.89,
"PERIODTYPE": "ACTUAL",
"NETINTERCHANGE": -828.1,
"SCHEDULEDGENERATION": 5362.3,
"SEMISCHEDULEDGENERATION": 1064.35
}
]
}
I think I am over complicating the issue, but I am confused
As mentioned in the comments above, you can paste the json as code.
Next you add a reference to Newtonsoft.Json:
dotnet add package newtonsoft.json
You then call JsonConvert.Deserialize<T>() as in the example below:
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using StackOverflow;
using System.Linq;
//In this example I load the JSON from disk
var json = File.ReadAllText("/home/timothy/data.json");
var record = JsonConvert.DeserializeObject<ServiceResponse>(json);
//No need to convert to List<T> if you're not going to filter it
var results = record.The5Min.ToList();
foreach(var item in results)
{
Console.WriteLine($"{item.Settlementdate}, {item.Regionid}");
}
namespace StackOverflow
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class ServiceResponse
{
[JsonProperty("5MIN")]
public The5Min[] The5Min { get; set; }
}
public partial class The5Min
{
[JsonProperty("SETTLEMENTDATE")]
public DateTimeOffset Settlementdate { get; set; }
[JsonProperty("REGIONID")]
public string Regionid { get; set; }
[JsonProperty("REGION")]
public string Region { get; set; }
[JsonProperty("RRP")]
public double Rrp { get; set; }
[JsonProperty("TOTALDEMAND")]
public double Totaldemand { get; set; }
[JsonProperty("PERIODTYPE")]
public string Periodtype { get; set; }
[JsonProperty("NETINTERCHANGE")]
public double Netinterchange { get; set; }
[JsonProperty("SCHEDULEDGENERATION")]
public double Scheduledgeneration { get; set; }
[JsonProperty("SEMISCHEDULEDGENERATION")]
public double Semischeduledgeneration { get; set; }
}
}

Cannot deserialize data with JsonUtility [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Serialize and Deserialize Json and Json Array in Unity
(9 answers)
Closed 3 years ago.
I'm new to using Json and I cant figure out why data isn't deserializing. I tried many things and I don't know what the problem is.
First I need to get data from this link https://jsonplaceholder.typicode.com/users
and then i need to deserialize it. (Need to use REST request)
Whenever I wanna use any property it tells me its NULL "NullReferenceException: Object reference not set to an instance of an object"
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System.Net;
using System.IO;
public class Houses : MonoBehaviour
{
public GameObject Prefab;
void Update()
{
if (Input.GetKey(KeyCode.T))
{
onClick();
}
}
public void onClick()
{
UnityWebRequest request = UnityWebRequest.Get("https://jsonplaceholder.typicode.com/users");
RootObject[] rootObjects = JsonUtility.FromJson<RootObject[]>(request.downloadHandler.text);
//Debug.Log(request.downloadHandler.text);
//foreach (var item in rootObjects)
//{
// Debug.Log(item.id);
//}
//----------------------------------------------------------------------------------------
//Latitude is the Y axis, longitude is the X axis
//for (int i = 0; i < rootObjects.Length; i++)
//{
// float x = float.Parse(rootObjects[i].address.geo.lng);
// float y = float.Parse(rootObjects[i].address.geo.lat);
// Instantiate(Prefab, new Vector3(x, y, 0f), Quaternion.identity);
//}
}
}
//public class ListItems
//{
// //public RootObject[] rootObjects;
//public List<RootObject> rootObjects;
//}
[System.Serializable]
public class Geo
{
public string lat { get; set; }
public string lng { get; set; }
}
[System.Serializable]
public class Address
{
public string street { get; set; }
public string suite { get; set; }
public string city { get; set; }
public string zipcode { get; set; }
public Geo geo { get; set; }
}
[System.Serializable]
public class Company
{
public string name { get; set; }
public string catchPhrase { get; set; }
public string bs { get; set; }
}
[System.Serializable]
public class RootObject
{
public int id; //{ get; set; }
public string name { get; set; }
public string username { get; set; }
public string email { get; set; }
public Address address { get; set; }
public string phone { get; set; }
public string website { get; set; }
public Company company { get; set; }
}
I would be really grateful if someone could help me out.
EDIT:
So i made some changes. Turns out thanks to you guys i didnt give the UnityWebRequest time to get the data.
Now im getting a different error "ArgumentException: JSON must represent an object type."
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System.Net;
using System.IO;
public class Houses : MonoBehaviour
{
public GameObject Prefab;
public string jsonURL;
void Update()
{
if (Input.GetKeyUp(KeyCode.T))
{
onClick();
}
}
public void processJsonData(string _url)
{
RootObject[] rootObjects = JsonUtility.FromJson<RootObject[]>(_url);
Debug.Log(rootObjects[0].id);
}
IEnumerator getData()
{
Debug.Log("Procesing data, please wait.");
//WWW _www = new WWW(jsonURL);
UnityWebRequest request = UnityWebRequest.Get("https://jsonplaceholder.typicode.com/users");
yield return request.SendWebRequest();
if (request.error == null)
{
processJsonData(request.downloadHandler.text);
}
else
{
Debug.Log("Oops something went wrong.");
}
}
public void onClick()
{
//----------------------------------------------------------------------------------------
//Latitude is the Y axis, longitude is the X axis
//for (int i = 0; i < rootObjects.Length; i++)
//{
// float x = float.Parse(rootObjects[i].address.geo.lng);
// float y = float.Parse(rootObjects[i].address.geo.lat);
// Instantiate(Prefab, new Vector3(x, y, 0f), Quaternion.identity);
//}
StartCoroutine(getData());
}
}
//public class ListItems
//{
// //public RootObject[] rootObjects;
//public List<RootObject> rootObjects;
//}
[System.Serializable]
public class Geo
{
public string lat;
public string lng;
}
[System.Serializable]
public class Address
{
public string street;
public string suite;
public string city;
public string zipcode;
public Geo geo;
}
[System.Serializable]
public class Company
{
public string name;
public string catchPhrase;
public string bs;
}
[System.Serializable]
public class RootObject
{
public int id;
public string name;
public string username;
public string email;
public Address address;
public string phone;
public string website;
public Company company;
}```
Untiy's JsonUtility is a relatively performant but also extremely limited serializer. It only supports serializing fields, while the objects you are trying to deserialize are entirely made up of properties, which it does not support.
(By the way, that Unity's default serializer doesn't support properties, is also why they don't show up in the editor while fields do.)
Since it doesn't know how to set the property, it doesn't, and the property remains with its default valuel. In the case of refrence types (string, Address, etc.) the default value is NULL, which makes trying to access them throw an exception.
All you have to do to fix this in your case is change the classes you want to deserialize so that this:
public class Geo
{
public string lat { get; set; }
public string lng { get; set; }
}
Becomes this:
public class Geo
{
public string lat;
public string lng;
}
Do that for all your classes, and you should be golden.
EDIT: As Philip B. Mentioned in his answer, you are also not using UnityWebRequest.Get correctly.
UnityWebRequest doesnt resolve immediatly, and you must either yield return... to it from inside a Unity Coroutine, or wait for it to resolve with a blocking loop like so:
UnityWebRequest request = UnityWebRequest.Get("https://jsonplaceholder.typicode.com/users");
request.SendWebRequest();
while (!request.isDone) {}
Of course this is considered very bad form, as it freezes the game untill the data is downloaded. However, under the hood Unity handles the downloads on background threads, so you won't be blocking the download itself while you wait.
You should also query the request to see if any errors came up so you can handle them if you want to, as you might also be having issues with the download itself.
if (request.isHttpError || request.isNetworkError)
{
//... handle errors here
}
else
{
RootObject[] rootObjects = JsonUtility.FromJson<RootObject[]>(request.downloadHandler.text);
}
However, I'd really recommend you use coroutines here as described in Unity's UnityWebRequest.Get documentation. If you're new to Unity Coroutines please read up, it's a valuable tool for Unity development.
EDIT 2: Per this answer JsonUtility doesn't support serializing an array as a top level object, so you'll have to wrap your array in an object first, and deserialize that. You'll also have to make the top level object in the json file an object that holds that array.
[Serializable]
public class Routes
{
public RootObject[] roots;
}
If you don't control the contents of the file, (and again this idea is coming from that excelent answer I linked to) you can do so with some string magic.
string jsonString = $#"{{""roots"":{request.downloadHandler.text}}}";
You are trying to access request.downloader.text which is NULL (hence the "NullReferenceException: Object reference not set to an instance of an object") since you didn't send your GET request.
If you follow this link on how to use UnityWebRequest.Get you will see that you need more than just UnityWebRequest.Get("Your_Url"); to get your JSON string from the URL.
Try the following :
public void onClick()
{
using (UnityWebRequest request = UnityWebRequest.Get("https://jsonplaceholder.typicode.com/users"))
{
request.SendWebRequest();
RootObject[] rootObjects = JsonUtility.FromJson<RootObject[]>(request.downloadHandler.text);
}
}
Hope this will help you.

How do I use Quicktype Json C# generated classes to Deserialize a JSON file

I have a very large Json file (cannot share)
Im using https://quicktype.io/csharp/ to generate a C# class from this json file
It gives me a class that looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace QuickType
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class Tem
{
[JsonProperty("Cal")]
public Cal Cal_ { get; set; }
}
public partial class Cal
{
[JsonProperty("Cam")]
public Camera[] Cam_ { get; set; }
[JsonProperty("Dis")]
public Dis[] Dis_ { get; set; }
[JsonProperty("Eye")]
public Eye[] Eye_ { get; set; }
[JsonProperty("Ine")]
public Ine[] Ine_ { get; set; }
[JsonProperty("Metadata")]
public Metadata Metadata_ { get; set; }
[JsonProperty("Tem")]
public Tem Tem_ { get; set; }
}
//...There are a lot more
}
Then it has some built internal classes
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
ShutterConverter.Singleton,
AssignedEyeConverter.Singleton,
LocationConverter.Singleton,
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
Not sure what to do with these
I tried to deserialize it this way but it didn't work, all the values were null
using (StreamReader r = new StreamReader(file path))
{
string json = r.ReadToEnd();
QuickType.Cal test = Newtonsoft.Json.JsonConvert.DeserializeObject<QuickType.Cal>(json);
}
I know that the file path is correct and the json string contains the json file. But I dont know how Im supposed to convert from Json.net to this Json generated class
Thanks,
As suggested above by Jeremy Thompson I switched to Json2csharp.com because the formatting is much simpler
Then I parse with Cal.RootObject test = Newtonsoft.Json.JsonConvert.DeserializeObject<Cal.RootObject>(json);

Visual Studio 2013 not recognizing reference to my new Model?

I'm working on an ASP.Net application. For one part of this, I have particular models stored in their own folder:
I have a reference to my Models/Default/ folder in one of my CustomControls: using Project.Models.Default; However, when I try to make a reference in my CustomControl YearsOfService to my default Model of Years_Of_Service, Visual Studio (2013) is not picking up either my Years_Of_Service or Years_Of_Service_Data model with my Models/Default/ folder:
Anyone have any ideas why this is happening?
EDIT:
Years_Of_Service.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace PROJECT.Models
{
public class YearsOfService
{
public string Year { get; set; }
public decimal ServiceCredited { get; set; }
public decimal Salary { get; set; }
public string CoveredEmployer { get; set; }
}
}
Years_Of_Service_Data.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace PROJECT.Models
{
public class YearsOfServiceData
{
public List<YearsOfService> YearsOfService { get; set; }
}
}
You currently have:
namespace PROJECT.Models
But this should also contain Default like this:
namespace PROJECT.Models.Default
So, it should end up like this:
namespace PROJECT.Models.Default
{
public class YearsOfServiceData
{
public List<YearsOfService> YearsOfService { get; set; }
}
}
Finally, you may want to keep your file names and class names the same otherwise it can get very confusing! So, stick with either Years_Of_Service_Data or YearsOfServiceData in both file and class name.
The classes contained in those files are just in the wrong namespace. Specify the correct one like this:
namespace XXXX.Models.Default
{
public class YearsOfService
{
//Snip
}
}
Alternatively, refer to them with their namespace as XXXX.Models.YearsOfService

add item into List<string> from another class in c#

I have 3 class. Those are places.cs, onePlace.cs and placestovisit.cs.
placestovisit.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sunamganj.ViewModels
{
public class placestovisit
{
public bool IsDataLoaded { get; set; }
public onePlace sunamganj { get; set; }
public static string basePlaces = "Assets/Places/";
private string baseTanguar = basePlaces + "Tanguar/";
private string baseBaruni = basePlaces + "Baruni/";
public void LoadData()
{
sunamganj = createSunamganj();
IsDataLoaded = true;
}
private onePlace createSunamganj()
{
onePlace data = new onePlace();
data.Items.Add(new places()
{
ID = "0",
Title = "Tanguar Haor",
shortDescription="Tanguar Haor (Lowlaying marsh) is a complex landscape of over 46 marshes, 30 km Northwest of Sunamgonj District.",
itemImage = baseTanguar + "1.jpg",
FullDescription = "Tanguar Haor (Lowlaying marsh) is a complex landscape of over 46 marshes, 30 km Northwest of Sunamgonj District. The marshes are inter connected with one another through narrow Channels but merge into a single large water body during monsoon. The aquatic vegetation and less disturbance from the human are instrument to invite a large variety of waterfowl specially winter migrant ducks that congregates in thousands. Resident and local migrant, raptor, waders and passerine birds made the area as one of the Asia's most potential birding place. Tanguar Haor is listed as a Ramsar site under the Ramsar Convention in 2000."
});
}
}
onePlace.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sunamganj.ViewModels
{
public class onePlace
{
public string Title { get; set; }
public List<places> Items { get; set; }
public onePlace()
{
Items = new List<places>();
}
}
}
places.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sunamganj.ViewModels
{
public class places
{
public string ID { get; set; }
public string Title { get; set; }
public string shortDescription { get; set; }
public string FullDescription { get; set; }
public string itemImage { get; set; }
public List<string>Gallery { get; set; }
}
}
I want to add item into Gallery from placestovisit class. For that what to do?
Actually I want to add one photo gallery for each object. But I am not so much good in OOP. At this moment can I go with this concept or need to change the concept. If I can go with this one then how can I add item into Gallery from placestovisit class?
Gallery is just a property of your places class, and you can add items by accessing that property via an instance of places class.
One thing you should remember that the properties of reference types are null by default, so you need to initialize them.You can do that in your constructor:
public class places
{
public places()
{
Gallery = new List<string>();
}
}
Then you can add new items to your list like:
var plc = new places() { /* set the properties */ }
plc.Gallery.Add("new gallery");

Categories