0

I am deserializing an XML file to a class. I am having trouble with the namespace(s).

When I use the attribute [XmlRoot(ElementName = "LandXML")] it deserializes ok however when I then serialize to an XML again the namespace is missing.

I have tried using the attribute [XmlRoot(ElementName = "LandXML",Namespace = "http://www.landxml.org/schema/LandXML-1.2")] however for some reason it wont deserialize?

My Deserialization Class LandXML

{
    // Commented out as it causes an error. 
    //[XmlRoot(ElementName = "LandXML",Namespace = "http://www.landxml.org/schema/LandXML-1.2")] 
   
    [XmlRoot(ElementName = "LandXML")]
    public class LandXML
    {

        [XmlElement(ElementName = "Units")]
        public Units Units { get; set; }

The Input XML File generate by a Leica application.

LandXML xmlns="http://www.landxml.org/schema/LandXML-1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.landxml.org/schema/LandXML-1.2 http://www.landxml.org/schema/LandXML-1.2/LandXML-1.2.xsd" version="1.2" date="2018-10-23" time="21:27:08.63" readOnly="false" language="English">
<Units>
...
</Units>

Deep within the Input XML there is also an element (& child elements) that have a different namespace as shown below:

<LandXML ...>
   <Units>
   ...
   </Units>
   <Survey>
   ...
   </Survey>
   <HexagonLandXML xmlns="http://xml.hexagon.com/schema/HeXML-1.8" xmlns:landxml="http://www.landxml.org/schema/LandXML-1.2" xsi:schemaLocation="http://xml.hexagon.com/schema/HeXML-1.8 http://xml.hexagon.com/schema/HeXML-1.8.xsd" averagingMode="Average" averagingMethod="Weighted" averagingPosLimit="0.010000" averagingHgtLimit="0.015000">
      <CoordinateSystem name="None">
      ...
      </CoordinateSystem>

My Deserialization class for the HexagonLandXML element. I tried the [XmlType] attribute to get the namespace but it did not seem to work?

// The following causes an error so I have commented out.
//[XmlType(Namespace = "http://xml.hexagon.com/schema/HeXML-1.8", TypeName = "HexagonLandXML")]

public class HexagonLandXML
{
    [XmlElement(ElementName = "Codelist")]
    public Codelist Codelist { get; set; }
}

My Output.xml File below without the correct namespaces. This file is created by a Serialize class I have written that simply serializes by LandXML object created above.

<LandXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" date="2022-06-22" time="16:31:46.94" version="1.2" language="English">
<Units>
...
</Units>
...
</Application>
<HexagonLandXML>
...
</HexagonLandXML>
</LandXML>

How can I change my class to correctly deal with the namespaces. My serialized Output.XML should be the same as my Deserialized Input.XML

SteveJ71
  • 15
  • 3
  • You have a default namespace xmlns (with no prefix). So change to : [XmlElement(ElementName = "Codelist", Namespace = `"http://xml.hexagon.com/schema/HeXML-1.8")]` A child node will inherit the default namespace of parent. – jdweng Mar 20 '23 at 14:42
  • The following may be helpful: https://stackoverflow.com/a/68232320/10024425 – Tu deschizi eu inchid Mar 20 '23 at 15:32
  • Thanks @jdweng. I am not sure I understand fully? I tried adding the namespace to the Codelist XmlElement attribute but still not working? – SteveJ71 Mar 20 '23 at 22:10
  • Solve one issue at a time. You have more than one issue. Try to isolate each issue one at a time by commenting lines of code to find out what is causing each issue. Work you way from top of xml getting one class to work at a time. I have add similar issues with deserializing xml and it is not easy. I cannot help with only the fragments you posted. Default namespaces are inherited from parents and without see all ascendants you cannot solve these issues. – jdweng Mar 21 '23 at 02:40

1 Answers1

0

I got it to work by using XmlReader. Previously I was trying to deserialize using XmlTextReader.

I used the following attributes in my Deserialization class.

  [XmlRoot(ElementName = "LandXML",Namespace = "http://www.landxml.org/schema/LandXML-1.2")]
  public class LandXML

  [XmlType(Namespace = "http://xml.hexagon.com/schema/HeXML-1.8", TypeName = "HexagonLandXML")]
  public class HexagonLandXML

My Deserialization Code

   public LandXML Deserialize_XmlReader()
    {

        LandXML landXML = new LandXML();

        // Create an instance of the XmlSerializer specifying type.
        XmlSerializer serializer = new XmlSerializer(typeof(Hexagon.LandXML));

        // Create the XmlSchemaSet class.
        XmlSchemaSet sc = new XmlSchemaSet();

        // Add the schemas to the collection.
        sc.Add("http://www.landxml.org/schema/LandXML-1.2", "http://www.landxml.org/schema/LandXML-1.2/LandXML-1.2.xsd");
        sc.Add("http://xml.hexagon.com/schema/HeXML-1.8", "http://xml.hexagon.com/schema/HeXML-1.8.xsd");

        XmlReaderSettings settings = new XmlReaderSettings();
        settings.IgnoreWhitespace = true;
        settings.IgnoreComments = true;
        settings.ValidationType = ValidationType.Schema;
        settings.Schemas = sc;

        XmlReader reader = XmlReader.Create(_filePath, settings);

        if (serializer.CanDeserialize(reader))
        {
            landXML = (Hexagon.LandXML)serializer.Deserialize(reader);
            return landXML;
        }

Previously, I was deserializing without properly adding the settings for the schemas. It now works fine and serializes as expected. Thanks @jdweng for taking the time to review. I took your advise and isolated the error one issue at a time.

SteveJ71
  • 15
  • 3