SeanThreeD
SeanThreeD

Reputation: 13

How to deserialize this XML document?

How do I deserialize this XML document structure with the C# XmlSerializer?

...
<Data>
    <Hotspot>
        <Properties>
            <xPos>0.5</xPos>
            <yPos>0.3</yPos>
            <alpha>0.1</alpha>
        </Properties>
        <Properties>
            <xPos>0.4</xPos>
            <yPos>0.7</yPos>
            <alpha>0.2</alpha>
        </Properties>
    </Hotspot>
    <Hotspot>
        <Properties>
            <xPos>0.1</xPos>
            <yPos>0.2</yPos>
            <alpha>0.9</alpha>
        </Properties>
        <Properties>
            <xPos>0.2</xPos>
            <yPos>0.3</yPos>
            <alpha>0.8</alpha>
        </Properties>
    </Hotspot>
</Data>

I'm working in Unity and I want to drive a GUI element with the position data in this XML document.

Here is my code for deserializing:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Xml.Serialization;
using System;
using System.IO;

public class Data
{
    public List<Hotspot> Hotspot;

    [XmlIgnore]
    public Data XmlData;

    public void Deserialize()
    {
        XmlSerializer deserializer = new XmlSerializer(typeof(Data));
        TextReader reader = new StreamReader(@"D:\Unity Projects\Axion800_Kabine\Assets\hspositions.xml");
        object obj = deserializer.Deserialize(reader);

        XmlData = (Data)obj;
        reader.Close ();
    }
}

public class Hotspot
{
    public List<Properties> Properties = new List<Properties>();
}

public class Properties
{
    public float xPos;
    public float yPos;

    public float alphaValue;
}

Just for testing purposes I made another script to actually use the XML data and attached it to a GUI element:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class UseXMLData : MonoBehaviour 
{
    private RectTransform rectTrans;
    private int _index = 0;

    private Data data;

    void Awake () 
    {
        data = new Data();
        data.Deserialize();
        rectTrans = GetComponent<RectTransform>();
    }

    void Update () 
    {
        rectTrans.anchoredPosition = new Vector2(data.XmlData.Hotspot[0].Properties[_index].xPos, data.XmlData.Hotspot[0].Properties[_index].yPos);
        _index++;

        if(_index == data.XmlData.Hotspot[0].Properties.Count - 1)
            _index = 0;
    }
}

This is the error message I receive:

ArgumentOutOfRangeException: Argument is out of range.
Parameter name: index
System.Collections.Generic.List`1[Properties].get_Item (Int32 index) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/List.cs:633)
UseXMLData.Update () (at Assets/UseXMLData.cs:21)

Looks to me like the XML data was never successfully read, so that the arrays contain no data. Have I done something wrong in how I set up the Data, Hotspot and Properties classes?

Many thanks for any help!

Sean

Upvotes: 0

Views: 325

Answers (2)

Volkan Paksoy
Volkan Paksoy

Reputation: 6977

If you decorate Hotspot and Properties collections with XmlElement attribute as below deserialization works fine:

public class Data
{
    [XmlElement("Hotspot")]
    public List<Hotspot> Hotspot;

    [XmlIgnore]
    public Data XmlData;

    public void Deserialize()
    {
        XmlSerializer deserializer = new XmlSerializer(typeof(Data));
        TextReader reader = new StreamReader(@"XMLFile1.xml");
        object obj = deserializer.Deserialize(reader);

        XmlData = (Data)obj;
        reader.Close();
    }
}

public class Hotspot
{
    [XmlElement("Properties")]
    public List<Properties> Properties = new List<Properties>();
}

public class Properties
{
    public float xPos;
    public float yPos;

    [XmlElement("alpha")]
    public float alphaValue;
}

Upvotes: 1

AntiHeadshot
AntiHeadshot

Reputation: 1130

In your XML you have

<alpha>???</alpha>

and in your class

public float alphaValue;

maybe using

public float alpha;

will work.

Upvotes: 0

Related Questions