Search Unity

XMLDocument Null reference in WinRTLegacy

Discussion in 'Windows' started by OnAndOn, Oct 26, 2015.

  1. OnAndOn

    OnAndOn

    Joined:
    Feb 14, 2015
    Posts:
    11
    I'm trying to parse an XML document on Windows Phone platform (WP8.1).
    I'm using Unity version 5.1.2f.
    Although I've seen at least one post with same issue from Jun 2014
    (http://forum.unity3d.com/threads/xml-load-on-wp8.249863/#post-1651943)

    I'm using defines as below (Although I don't know when NETFX_CORE gets defined or if it is even correct or valid anymore. I saw it on numerous XML related issues in this forum, so using them)

    Code (CSharp):
    1. #if NETFX_CORE && !UNITY_EDITOR
    2. using XmlReader = WinRTLegacy.Xml.XmlReader;
    3. #else
    4. using XmlReader = System.Xml.XmlReader;
    5.  
    The code in question is like:
    Code (CSharp):
    1. XmlDocument xml = new XmlDocument();
    2. xml.LoadXml(xmlString);
    I've triple checked the validity of xmlString externally and it is a valid XML. The code runs fine as it is on Android and in Editor.

    The XML in question does have a DTD header though. Exception I get is:

    Code (CSharp):
    1. Exception: Object reference not set to an instance of an object.
    2. Type: System.NullReferenceException
    3. Module: WinRTLegacy
    4. InnerException: <No Data>
    5. AdditionalInfo:<No Data>
    6.   at System.Xml.XmlDocumentType.ImportFromDTD()
    7.   at System.Xml.XmlDocumentType..ctor(String name, String publicId, String systemId, String internalSubset, XmlDocument doc)
    8.   at System.Xml.XmlDocument.CreateDocumentType(String name, String publicId, String systemId, String internalSubset)
    9.   at System.Xml.XmlDocument.ReadNodeCore(XmlReader reader)
    10.   at System.Xml.XmlDocument.ReadNode(XmlReader reader)
    11.   at System.Xml.XmlDocument.Load(XmlReader xmlReader)
    12.   at System.Xml.XmlDocument.LoadXml(String xml)
    So next I tried using XmlReader:
    Code (CSharp):
    1. var xmlReader = XmlReader.Create(new System.IO.StringReader(xmlString));
    2.    
    3. xml.Load(xmlReader);
    which got me:

    Code (CSharp):
    1. Exception: Method not found: 'Void System.Xml.XmlDocument.Load(System.Xml.XmlReader)'.
    2. Type: System.MissingMethodException
    3. Module: Assembly-CSharp
    4. InnerException: <No Data>
    5. AdditionalInfo:<No Data>
    So how come the System.Xml.XmlDocument.Load(XmlReader xmlReader) call works in first stack trace but if I tried to call manually gives me MissingMethodException under same defines in my class. I MUST NOT be using correct defines. What is a correct define in place of NETFX_CORE?

    Also for first Null reference, which is the real issue, is it because of DTD tag (<!DOCTYPE ...>)? I am only guessing from the System.Xml.XmlDocumentType.ImportFromDTD() frame in first stack trace.

    I checked what I could from WinRTLegacy in ILSpy and:

    System.Xml.XmlDocumentType constructor seems to be creating a new instance of Mono.Xml2.XmlTextReader and then doing:
    this.dtd = xmlTextReader.DTD;

    But that property in XmlTextReader seems to be defined as:
    Code (CSharp):
    1. internal DTDObjectModel DTD
    2. {
    3.   get
    4.   {
    5.   return null;
    6.   }
    7. }
    And then in ImportFromDTD() it has:

    Code (CSharp):
    1. using (IEnumerator<DTDNode> enumerator = this.DTD.EntityDecls.Values.GetEnumerator())
    2.   {
    3.   ......................
    4. }
    (DTD is wrapping dtd)

    I could be way, way off here as I'm looking with ILSpy. So this may be discarded.

    However if the DTDs are not supported then can we NOT have a hard fail like this. (skip the call to create document type? OR Just skip over the DOCTYPE element or create a default xmlNode. etc.)

    I really would like to have the DTD in XMLs as some external tools in pipeline also use the same XML and XML itself is generated by third party tools. If parsing support is not there then it's fine but if the XML itself could get through then that is more than enough.

    Is there any other code flow I can use to not run into this as a workaround?
     
  2. Tomas1856

    Tomas1856

    Unity Technologies

    Joined:
    Sep 21, 2012
    Posts:
    3,919
  3. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,736
    System.Xml replacements in WinRTLegacy are limited, they don't provide full functionality of original System.Xml.
    For certain we don't support XPath and XML schema validation, don't remember exactly about DTD, but likelily this is missing too.
    So if you do need those, you should use stuff fraom either System.Xml.Linq or Windows.Data.Xml namespaces.
     
  4. OnAndOn

    OnAndOn

    Joined:
    Feb 14, 2015
    Posts:
    11
    I didn't know XDocument and Xml.Linq works in Unity. I'll be using those in future.

    But for the code I'm right now looking at Windows.Data.Xml seems easy to migrate to. Code in question is pretty trivial DOM access and then XPath-esque logic is built in own code on top of that.
    So I believe as long as I stay away from XPath related methods in Windows.data.Xml.dom.XmlDocument itself (SelectNode*** etc) I should be fine; is this correct?