[SOLVED] Read values from class inside array?

Hi
This is the scenario:
I open an XML file with the following content:

<?xml version="1.0" encoding="Windows-1252"?>
<Resources xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 
 
  <Resource>
    <type>container</type>
    <codename>resource_crate</codename>
    <name>Crate</name>
    <health>100</health>
    <changeType>null</changeType>
    <changeValue>0</changeValue>
    <information>A crate that may have some useful items inside.</information>
    <mineable>false</mineable>
    <tool>null</tool>
    <fragments>0</fragments>
    <crosshair>crosshairHand</crosshair>
  </Resource>

  <Resource>
    <type>item</type>
    <codename>item_waterpellet</codename>
    <name>Water pellet</name>
    <health>100</health>
    <changeType>liquids</changeType>
    <changeValue>5</changeValue>
    <information>When you feel thirsty.</information>
    <mineable>false</mineable>
    <tool>null</tool>
    <fragments>0</fragments>
    <crosshair>crosshairHand</crosshair>
  </Resource>

  <Resource>
    <type>item</type>
    <codename>item_nutritionpellet</codename>
    <name>Nutrition pellet</name>
    <health>100</health>
    <changeType>nutrition</changeType>
    <changeValue>3</changeValue>
    <information>When you feel hungry.</information>
    <mineable>false</mineable>
    <tool>null</tool>
    <fragments>0</fragments>
    <crosshair>crosshairHand</crosshair>
  </Resource>

</Resources>

I then want to save every Resource in a class that looks like this:

public class resourcesList {
    string type;
    string codename;
    string name;
    string health;
    string changeType;
    string changeValue;
    string information;
    string mineable;
    string tool;
    string fragments;
    string crosshair;

    public resourcesList(string newType, string newCodename, string newName, string newHealth, string newChangeType, string newChangeValue, string newInformation, string newMineable, string newTool, string newFragments, string newCrosshair) {
        type = newType;
        codename = newCodename;
        name = newName;
        health = newHealth;
        changeType = newChangeType;
        changeValue = newChangeValue;
        information = newInformation;
        mineable = newMineable;
        tool = newTool;
        fragments = newFragments;
        crosshair = newCrosshair;
    }

}

To do this I use:

public ArrayList myArrayList = new ArrayList();

    void getResources() {
        doc.Load(xmlResoursPath);

        XmlNode baseNode = doc.DocumentElement; // Resources
        XmlNode childNode;
        int nTopNodes = baseNode.ChildNodes.Count;

        for (int i = 0; i < nTopNodes; i++) {
            childNode = baseNode.ChildNodes[i];
            myArrayList.Add(new resourcesList(
                childNode.SelectSingleNode("type").InnerText,
                childNode.SelectSingleNode("codename").InnerText,
                childNode.SelectSingleNode("name").InnerText,
                childNode.SelectSingleNode("health").InnerText,
                childNode.SelectSingleNode("changeType").InnerText,
                childNode.SelectSingleNode("changeValue").InnerText,
                childNode.SelectSingleNode("information").InnerText,
                childNode.SelectSingleNode("mineable").InnerText,
                childNode.SelectSingleNode("tool").InnerText,
                childNode.SelectSingleNode("fragments").InnerText,
                childNode.SelectSingleNode("crosshair").InnerText
                ));
        }

    }

But I cant figure out how to get the values “nodevalues” out of it again.
For example: if I want to know the [codename] of the second Resource in the xml file, how do I do that?

By using “Debug.Log(myArrayList[1])” it only show the output “resourcesList”…

You might want to look into using an XmlSerializer. That will take a lot of the headaches away.

Having said that, all member fields you have declared in the resourcesList class are private, and can thus only be accessed by the class itself.

1 Like

Yes, tried it with public, with no success… I will try with XmlSerializer… it seems a bit easier.

OK, im going to see if I can find a tutorial on all this :slight_smile:

Ok, I give up.

If someone could help me with this I would be very grateful.

I would like to open the file “Resource.xml” in the folder “xml” that exists in a subfolder of Assets.

Resource.xml:

<?xml version="1.0" encoding="Windows-1252"?>
<Resources xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <Resource>
    <type>container</type>
    <codename>resource_crate</codename>
    <name>Crate</name>
    <health>100</health>
    <changeType>null</changeType>
    <changeValue>0</changeValue>
    <information>A crate that may have some useful items inside.</information>
    <mineable>false</mineable>
    <tool>null</tool>
    <fragments>0</fragments>
    <crosshair>crosshairHand</crosshair>
  </Resource>

  <Resource>
    <type>item</type>
    <codename>item_waterpellet</codename>
    <name>Water pellet</name>
    <health>100</health>
    <changeType>liquids</changeType>
    <changeValue>5</changeValue>
    <information>When you feel thirsty.</information>
    <mineable>false</mineable>
    <tool>null</tool>
    <fragments>0</fragments>
    <crosshair>crosshairHand</crosshair>
  </Resource>

  <Resource>
    <type>item</type>
    <codename>item_nutritionpellet</codename>
    <name>Nutrition pellet</name>
    <health>100</health>
    <changeType>nutrition</changeType>
    <changeValue>3</changeValue>
    <information>When you feel hungry.</information>
    <mineable>false</mineable>
    <tool>null</tool>
    <fragments>0</fragments>
    <crosshair>crosshairHand</crosshair>
  </Resource>

</Resources>

I then want to read all the nodes and put them in a array so I can later get info from that array in the following way:

valueFromArray = theArray[0][0] “and that would then be [ container ] as you can see in the Resource.xml above”
and
valueFromArray = theArray[0][1] “would then be [ resource_crate] as you can see in the Resource.xml above”

A working example is what I need. Or some really good tutorial so I can make it myself.

If you edit the xml to look something like this:

<ResourceCollection>
   <Resources>
      <Resource>
       <Type>container</Type>
       <Codename>resource_crate</Codename>
       <Name>Crate</Name>
       <Health>100</Health>
       <ChangeType>null</ChangeType>
       <ChangeValue>0</ChangeValue>
       <Information>A crate that may have some useful items inside.</Information>
       <Mineable>false</Mineable>
       <Tool>null</Tool>
       <Fragments>0</Fragments>
       <Crosshair>crosshairHand</Crosshair>
     </Resource>
   </Resources>
</ResourceCollection>

Then I believe something like this should work:

public class ResourceHandler
{
    public ResourceCollection GetResources()
    {
        string filename = //path to file
       
        XmlSerializer serializer = new XmlSerializer(typeof(ResourceCollection));
        FileStream fs = new FileStream(filename, FileMode.Open);
        ResourceCollection collection;
        collection = (ResourceCollection) serializer.Deserialize(fs);
       
        return collection;
    }
}

public class ResourceCollection
{
    public Resource[] Resources;
}

public class Resource
{
    public string Type;
    public string Codename;
    public string Name;
    public string Health;
    public string ChangeType;
    public string ChangeValue;
    public string Information;
    public string Mineable;
    public string Tool;
    public string Fragments;
    public string Crosshair;
}

Thanks, but how do I get the information from the Array? and why is " public Resource[ ] Resources; " in a class called the same as another class? Why not put them in the same class?

I found out how to get it :slight_smile:
Is this correct?:

ResourceHandler rh = new ResourceHandler();
        ResourceCollection r = rh.GetResources();
        Debug.Log(r.Resources[0].Codename);

That should be it yeah :slight_smile:

1 Like

Hmm… maybe you know this one also Timelog?

I have made 2 Dictionaries:

    private Dictionary<int, Dictionary<string,string>> dict = new Dictionary<int, Dictionary<string, string>>();
    private Dictionary<string, string> dict2 = new Dictionary<string, string>();

I have then filled them with a id and the xml items like this:

for (int i = 0; i < resourcesXML.Resources.Length; i++) {
            if (resourcesXML.Resources[i].Type == "item") {
                dict2.Add(resourcesXML.Resources[i].Codename, resourcesXML.Resources[i].Name);
                dict.Add(i, dict2);
            }
        }

The Dictionary “dict” is a Dictionary where all my items will be kept. I then want to select 5 or more items from this Dictionary randomly “can be same item several times”.
To do this I make a new List:

private List<int> chosenCrateItems = new List<int>();

And I populate it with random numbers from the length of the dict:

    for (int i = 0; i < maxAmountOfContent; i++) {
            chosenCrateItems.Add(Random.Range(1, dict.Count));
        }

So far all ok, but now the problem comes.
I now want to get the Name of the items in the “dict” that has the same id as the id:s in the List chosenCrateItems .
So if the chosenCrateItems contains {1,2,1,1,2,}, the output should be “example: If 1 = Water pellet and 2 = Nutrition pellet”:

Water pellet : 3
Nutrition pellet: 2

I have tried different methods, but I cant get it working.

I will change to object array for this. I think that will be easier to work with then 2 dictionaries.

OK, I fixed it :slight_smile:

        ClearLog();
        GameObject GlobalVariables = GameObject.Find("GlobalVariables");
        ResourceCollection resourcesXML;
        ResourceHandler rh = new ResourceHandler();
        resourcesXML = rh.GetResources();

        // Create the 2dArray of items that the box will contain
        object[,] crateItems = new object[maxAmountOfContent,2];

        // get number of Items in the xml [START]
        for (int i = 0; i < resourcesXML.Resources.Length; i++) {
            if (resourcesXML.Resources[i].Type == "item") {
                numberOfItems++;
            }
        }
        // get number of Items in the xml  [END]

        // Create a 2dArray with the length of the number of Items
        object[,] listOfItems = new object[numberOfItems, 2];

        // Put all Items in above 2dArray [START]
        int i2 = 0;
        for (int i = 0; i < resourcesXML.Resources.Length; i++) {
            if (resourcesXML.Resources[i].Type == "item") {
                listOfItems[i2, 0] = resourcesXML.Resources[i].Codename;
                listOfItems[i2, 1] = resourcesXML.Resources[i].Name;
                i2++;
            }
        }
        // Add all Items in above 2dArray [END]

        // Random select from all items in 2dArray listOfItems and add to 2dArray crateItems [START]
        int x = listOfItems.GetLength(0);
        int y = 0;
        for (int i = 0; i < maxAmountOfContent; i++) {
            y = Random.Range(0, x);
            crateItems[i, 0] = listOfItems[y,0];
            crateItems[i, 1] = listOfItems[y,1];
        }
        // Random select from all items in 2dArray listOfItems and add to 2dArray crateItems [END]

Now I get it as I wanted to have it from the start. 2dArray with object seems to be the way I had to go. I maybe could use ArrayList also?

Don’t use arraylist. If you are going to be modifying the collection, use a normal List.

Also sorry for not responding, am kinda sick atm :frowning:

1 Like