Search Unity

XmlElement.GetAttribute returns null

Discussion in 'Scripting' started by hedgeh0g, May 13, 2020.

  1. hedgeh0g

    hedgeh0g

    Joined:
    Jul 18, 2014
    Posts:
    102
    I'm trying to build a localization system based on XML:

    Code (CSharp):
    1. <?xml version="1.0" encoding="utf-8"?>
    2. <languages>
    3.   <English>
    4.   <!-- Login -->
    5.       <string name="login_status_offline">Offline.</string>
    6.       <string name="login_status_connecting">Connecting...</string>
    7.       <string name="login_status_generic_error">Connection error. Server may be unavailable.</string>
    8.       <string name="login_status_login_error">Error. Invalid email or password.</string>
    9.   </English>
    10.  
    11. </languages>
    Now, I need to read my XML and put the localization data into an hashtable:

    Code (CSharp):
    1. var xml = new XmlDocument();
    2.         xml.Load(filePath);
    3.        
    4.         xml_lines = new Hashtable();
    5.  
    6.         XmlElement doc_element = xml.DocumentElement;
    7.  
    8.         if (doc_element != null)
    9.         {
    10.             var elemEnum = doc_element.GetEnumerator();
    11.  
    12.             while (elemEnum.MoveNext())
    13.             {
    14.                 xml_lines.Add((elemEnum.Current as XmlElement).GetAttribute("name"), (elemEnum.Current as XmlElement).InnerText);
    15.             }
    16.         }
    Turns out I'm getting only one record with key "" and value "Offline.Connecting...Connection error. Server may be unreachable.Error. Invalid email or password." Basically, the attribute "name" is either ignored or unrecognized. I'm struggling because I don't know if the problem is on my code or on the XML. Though, the XML looks valid. What can I do?

    Thanks in advance.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,736
    This is the main problem with XML. Even when it appears to a mortal human to be correct, there is usually some maddeningly obtuse or obscure reason it fails to load.

    Personally I would switch to using JSON.

    Unfortunately the "teeny-tiny JSON" that Unity implements does not support dictionaries, which is essentially the structure you need.

    Fortunately there is a full-featured JSON .NET package available free on the asset store that does.

    Once you go JSON the world will be a far friendlier place. As a wise man once said,

    "Let's say you have a problem and you decide to use XML. Now you have two problems."

    As I say, "Friends don't let friends use XML."

    Also, "XML... not even once."
     
    PraetorBlue likes this.
  3. R1PFake

    R1PFake

    Joined:
    Aug 7, 2015
    Posts:
    542
    Some hints, it looks like you are using the "old" XML classes, there is a newer way to use XML in C# in the System.Xml.Linq namespace with classes like XDocument. But the "old" classes should still work fine for your use case.

    My next question would be, why are you "parsing" the XML yourself instead of using the serialization tool from the framework which will parse the XML to your classes and give you detailed error messages (with things like line numbers) if the XML is invalid?

    I don't know the exact error in your code, because I don't have time to debug right now, but you can debug it yourself. I don't want to sound rude, but do you know how to debug code? Because with a debugger it would be very easy to step into your code lines and check what's going on and then you will find the error very fast.

    I don't agree with the comment above, I don't want to say XML or JSON is better, but I used XML for years and never had any problems or unknown failing issues. But the main difference is that I don't parse my XML "by hand" I use serialization and like I said above any decent serialization class will output decent error messages if the XML is invalid for some reason.