Search Unity

Loading XML from StreamAssets not working

Discussion in 'Web' started by Deleted User, Nov 23, 2015.

  1. Deleted User

    Deleted User

    Guest

    Hallo everyone,


    I am trying to load the XML file "hspositions.xml", located in "/Assets/StreamingAssets/" at runtime using C#'s XMLSerializer. This is working fine in the Editor and the Standalone build, but fails in WebGL.


    First of all here is the class structure I am using to store the deserialized XML content, which also contains the DeSerialize() method:


    Code (CSharp):
    1. [XmlRoot("Data")]
    2. public class DataCollection
    3. {
    4.     [XmlElement("Hotspot")]
    5.     public List<Hotspot> Hotspot;
    6.  
    7.     public static DataCollection DeSerialize(string path)
    8.     {
    9.         XmlSerializer serializer = new XmlSerializer(typeof(DataCollection));
    10.         using(var stream = new FileStream(path, FileMode.Open))
    11.         {
    12.             return serializer.Deserialize(stream) as DataCollection;
    13.         }
    14.     }
    15. }
    16.  
    17. public class Hotspot
    18. {
    19.     [XmlElement("Properties")]
    20.     public List<Properties> Properties = new List<Properties>();
    21. }
    22.  
    23. public class Properties
    24. {
    25.     public float xPos;
    26.     public float yPos;
    27.  
    28.     public float alphaValue;
    29. }
    30.  


    And in a seperate class that I attach to an empty GameObject, I call the DeSerialize() method like that:


    Code (CSharp):
    1.  
    2. public class XMLDeserializer : MonoBehaviour
    3.  
    4. {
    5.  
    6.   public static DataCollection XmlData;
    7.  
    8.  
    9.   void Awake ()
    10.  
    11.   {
    12.  
    13.   XmlData = DataCollection.DeSerialize(Path.Combine(Application.streamingAssetsPath, "hspositions.xml"));
    14.  
    15.   }
    16.  
    17. }

    The deserialized data is then used by GUI elements to drive their position. However, I don't think the XML data is ever read in.
    When I make a WebGL Development Build, and run the application locally in Firefox, I receive this Debug information in the Firefox Browser Console:



    And here the rest of the Debug Log:


    The first part seems to indicate that the WebGL build doesn't find the path the XML file is stored in. Not sure why though. For the rest, I have absolutely no idea how to interpret it as I am rather new to C# programming.


    I would really appreciate any hint to a solution!


    Thanks!

    Sean
     
  2. Marco-Trivellato

    Marco-Trivellato

    Unity Technologies

    Joined:
    Jul 9, 2013
    Posts:
    1,654
    it looks like there is a slash at the beginning of the path, and a missing one after 'file:/'. Which Unity version is this ?
     
  3. Deleted User

    Deleted User

    Guest

    Hi,

    I am using Version 5.2.2f1. Is this a bug or is there something wrong with my code?
     
  4. Deleted User

    Deleted User

    Guest

    A small Update:

    After reading this entry http://docs.unity3d.com/ScriptReference/Application-streamingAssetsPath.html
    in the documentation I converted my XMLDeserializer class to:


    Code (CSharp):
    1. public class XMLDeserializer : MonoBehaviour
    2. {
    3.     public static DataCollection XmlData;
    4.  
    5.     public string filePath;
    6.  
    7.     public string result = "";
    8.  
    9.  
    10.     IEnumerator Example()
    11.     {
    12.         if(filePath.Contains("://"))
    13.         {
    14.             WWW www = new WWW(filePath);
    15.             yield return www;
    16.             result = www.text;
    17.  
    18.             Debug.Log ("result: " +www.text);
    19.  
    20.             XmlData = DataCollection.DeSerialize(result);
    21.         }
    22.         else
    23.         {
    24.             XmlData = DataCollection.DeSerialize(filePath);
    25.         }
    26.     }
    27.     void Awake ()
    28.     {
    29.         filePath = Path.Combine(Application.streamingAssetsPath, "hspositions.xml");
    30.  
    31.         StartCoroutine("Example");
    32.  
    33.     }
    34.  
    According to the Firefox Browser Controle, the path is now properly resolved with the other errors remaining:

    Unforetunately the WebGL build still fails, even when I am doing a regular build, i.e. not a development build. I get the message:

    " The browser could not allocate enought memory for the WebGL content. If you are the developer of this content, try allocating less memory to your WebGL build in the WebGL settings."

    Currently I have it set to 512MB. Should I try even less?
     
  5. Marco-Trivellato

    Marco-Trivellato

    Unity Technologies

    Joined:
    Jul 9, 2013
    Posts:
    1,654
    Yes! How much do you need ? If you don't know, the memory profiler "Reserved Total" will give you an idea (perhaps use a little extra to be safe)
     
  6. Deleted User

    Deleted User

    Guest

    Hm strange, I just closed Firefox and launched the index.html again and this time the application started without the memory error message. But the XML position data is still not being used. BUT I think it finally found the XML file. The Browser Console now reports:

    That index out of range error is familiar to me. Could it be that the XML Serializer doesn't like the List<> type in my DataCollection class? So it now seems to find the XML file, but can't fill the Lists<> as it needs an array?
     
  7. Deleted User

    Deleted User

    Guest

    Since I'm using arrays, that index out of range error is gone, but the position data is still not used properly it seems. There are two errors remaining:

    The Browser Console shows that the XML file is probably not read in in its entirety as the console windows displays only about half of the file contents. Not sure though if this is a certain indication that some contents weren't loaded.
     
  8. Deleted User

    Deleted User

    Guest

    I now managed to read in the XML file. What I did was copy the XML file to the Assets/Resources which automatically converts the XML file into a TextAsset. Then I used Resources.Load<TextAsset> to read the file. Here is my new DeSerialize() function:

    Code (CSharp):
    1.     public static DataCollection DeSerialize()
    2.     {
    3.         using(TextReader textReader = new StringReader(Resources.Load<TextAsset>("hspositions").text))
    4.         {
    5.             XmlSerializer serializer = new XmlSerializer(typeof(DataCollection));
    6.          
    7.             DataCollection XmlData = serializer.Deserialize(textReader) as DataCollection;
    8.  
    9.             return XmlData;
    10.         }
    11.     }
    And simply calling it from another class like that:

    Code (CSharp):
    1. void Awake()
    2. {
    3. XmlData = DataCollection.DeSerialize();
    4. }
    This did not work locally in Firefox, but only after I uploaded the WebGL files to a server.
     
    Last edited by a moderator: Nov 24, 2015
    murkantilism likes this.
  9. Deleted User

    Deleted User

    Guest

    Cool, got it to work now with the XML in StreamingAssets. That even works locally in Firefox!

    Here is the code:

    Code (CSharp):
    1.     public static DataCollection DeSerialize(WWW www)
    2.     {
    3.         using(TextReader textReader = new StringReader(www.text))
    4.         {
    5.             XmlSerializer serializer = new XmlSerializer(typeof(DataCollection));
    6.          
    7.             DataCollection XmlData = serializer.Deserialize(textReader) as DataCollection;
    8.  
    9.             return XmlData;
    10.         }
    11.     }

    And the calling class:


    Code (CSharp):
    1. public class XMLDeserializer : MonoBehaviour
    2. {
    3.     public static DataCollection XmlData;
    4.  
    5.     public static string filePath;
    6.  
    7.     IEnumerator ParseXML()
    8.     {
    9.         if(filePath.Contains("://"))
    10.         {
    11.             WWW www = new WWW(filePath);
    12.             yield return www;
    13.  
    14.             XmlData = DataCollection.DeSerialize(www);
    15.         }
    16.         else
    17.         {
    18.             XmlData = DataCollection.DeSerialize(filePath);
    19.         }
    20.     }
    21.     void Awake ()
    22.     {
    23.         filePath = Path.Combine(Application.streamingAssetsPath, "hspositions.xml");
    24.  
    25.         StartCoroutine("ParseXML");
    26.     }

    So basically I created an overload for the DeSerialize() method taking in a WWW object as paramter. Within the DeSerialize() method I'm then creating a TextReader with www.text as parameter which in turn I feed into the XmlSerializer. Hope this helps!
     
    Last edited by a moderator: Nov 25, 2015
    murkantilism likes this.
  10. payalzariya07

    payalzariya07

    Joined:
    Oct 5, 2018
    Posts:
    85
    how to download file using url ?