0

I am working on an application where I need to convert string XML into C# object but I am receiving following error.

There is an error in XML document (1, 23) InvalidOperationException: was not expected.

Here is my XML

<root>
  <main>
    <url>https://w3.kubotalink.com/KLWebServices/services/DealerInventorySOAP</url>
    <timeout>80</timeout>
    <financialuploaddealernumber>50057</financialuploaddealernumber>
    <ikqunitcategories>2,3,4,5,6,7,8,9,10,11,12</ikqunitcategories>
    <ikqdebuglogenabled>true</ikqdebuglogenabled>
    <adminuserid>128</adminuserid>
    <locatoradminuserid>120</locatoradminuserid>
    <warrantyenabled>true</warrantyenabled>
    <warrantyusernameproduction>integration@chartersoftware.com.ktc</warrantyusernameproduction>
    <warrantypasswordproduction>KubotaWarranty-1</warrantypasswordproduction>
    <warrantyusernamestaging>integration@chartersoftware.com.ktc.uat</warrantyusernamestaging>
    <warrantypasswordstaging>Ktcwarranty1</warrantypasswordstaging>
    <warrantytestmode>true</warrantytestmode>
  </main>
  <locationsettings>
    <row>
      <dealerid>51760</dealerid>
      <locationid>1</locationid>
      <passkey>kubota </passkey>
      <enablelocator>false</enablelocator>
      <ikquserid>ikqTest1</ikquserid>
      <ikqpass>qwerty</ikqpass>
      <ikqsalespersonid>144</ikqsalespersonid>
      <ikqcustomerid>4</ikqcustomerid>
      <ikqcustomerno>ABBOTT TOM</ikqcustomerno>
      <ikqmiscchargeid>16</ikqmiscchargeid>
      <ikqmiscchargename>SETUP</ikqmiscchargename>
      <ikqunitcategoryid>11</ikqunitcategoryid>
      <createpackingslips>true</createpackingslips>
    </row>
    <row>
      <dealerid>51760</dealerid>
      <locationid>2</locationid>
      <passkey>family2014</passkey>
      <enablelocator>false</enablelocator>
      <ikquserid />
      <ikqpass />
      <ikqsalespersonid>-2147483648</ikqsalespersonid>
      <ikqcustomerid>-2147483648</ikqcustomerid>
      <ikqcustomerno />
      <ikqmiscchargeid>-2147483648</ikqmiscchargeid>
      <ikqmiscchargename />
      <ikqunitcategoryid>-2147483648</ikqunitcategoryid>
      <createpackingslips>true</createpackingslips>
    </row>
    <row>
      <dealerid>51760</dealerid>
      <locationid>3</locationid>
      <passkey>family2014</passkey>
      <enablelocator>false</enablelocator>
      <ikquserid />
      <ikqpass />
      <ikqsalespersonid>-2147483648</ikqsalespersonid>
      <ikqcustomerid>-2147483648</ikqcustomerid>
      <ikqcustomerno />
      <ikqmiscchargeid>-2147483648</ikqmiscchargeid>
      <ikqmiscchargename />
      <ikqunitcategoryid>-2147483648</ikqunitcategoryid>
      <createpackingslips>true</createpackingslips>
    </row>
    <row>
      <dealerid>48375</dealerid>
      <locationid>6</locationid>
      <passkey>charterkub1</passkey>
      <enablelocator>false</enablelocator>
      <ikquserid />
      <ikqpass />
      <ikqsalespersonid>-2147483648</ikqsalespersonid>
      <ikqcustomerid>-2147483648</ikqcustomerid>
      <ikqcustomerno />
      <ikqmiscchargeid>-2147483648</ikqmiscchargeid>
      <ikqmiscchargename />
      <ikqunitcategoryid>-2147483648</ikqunitcategoryid>
      <createpackingslips>false</createpackingslips>
    </row>
    <row>
      <dealerid>51760</dealerid>
      <locationid>8</locationid>
      <passkey>family2014</passkey>
      <enablelocator>false</enablelocator>
      <ikquserid />
      <ikqpass />
      <ikqsalespersonid>-2147483648</ikqsalespersonid>
      <ikqcustomerid>-2147483648</ikqcustomerid>
      <ikqcustomerno />
      <ikqmiscchargeid>-2147483648</ikqmiscchargeid>
      <ikqmiscchargename />
      <ikqunitcategoryid>-2147483648</ikqunitcategoryid>
      <createpackingslips>true</createpackingslips>
    </row>
  </locationsettings>
</root>

Here is Model Class

[Serializable, XmlRoot("locationsettings")]
    public class LocationSettings
    {
        public LocationSettings()
        {
            this.RowSettings = new List<RowSettings>();
        }
        [XmlArrayItem("row")]
        public List<RowSettings> RowSettings { get; set; }
    }
    [Serializable, XmlRoot("row")]
    public class RowSettings
    {
        [XmlElement("dealerid")]
        public int dealerid { get; set; }
        [XmlElement("locationid")]
        public int locationid { get; set; }
        [XmlElement("ikquserid")]
        public string? ikquserid { get; set; }
        [XmlElement("ikqpass")]
        public string? ikqpass { get; set; }
    }

Here is my code item.Settings contains the above XML in string.

var xmlSettings = $"<?xml version=\"1.0\"?>{item.Settings}";
    var stringReader = new System.IO.StringReader(xmlSettings);
    var serializer = new XmlSerializer(typeof(LocationSettings));
    var tt = serializer.Deserialize(stringReader) as LocationSettings;

I just need to serialize the XML into LocationSettings Class I do not want to read the other data.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
Muhammad Kamran
  • 105
  • 1
  • 11

2 Answers2

1

Following code is tested. I changed [XmlArrayItem] to [XmlElement]

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace ConsoleApplication52
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";

        static void Main(string[] args)
        {
            string xml = File.ReadAllText(FILENAME);
            StringReader sReader = new StringReader(xml);
            XmlReader xReader = XmlReader.Create(sReader);
            xReader.ReadToFollowing("locationsettings");
            XmlSerializer serializer = new XmlSerializer(typeof(LocationSettings));
            LocationSettings location = (LocationSettings)serializer.Deserialize(xReader);
        }
    }
    [Serializable, XmlRoot("locationsettings")]
    public class LocationSettings
    {
        public LocationSettings()
        {
            this.RowSettings = new List<RowSettings>();
        }
        [XmlElement("row")]
        public List<RowSettings> RowSettings { get; set; }
    }
    [Serializable, XmlRoot("row")]
    public class RowSettings
    {
        [XmlElement("dealerid")]
        public int dealerid { get; set; }
        [XmlElement("locationid")]
        public int locationid { get; set; }
        [XmlElement("ikquserid")]
        public string ikquserid { get; set; }
        [XmlElement("ikqpass")]
        public string ikqpass { get; set; }
    }

 
}
jdweng
  • 33,250
  • 2
  • 15
  • 20
1

Changing [XmlArrayItem] to [XmlElement] in LocationSettings model does the trick. Following code works:

var xmlContent = File.ReadAllText("foo.xml");

var xml = XDocument.Parse(xmlContent);
var locationSettingsElement = xml.Root!.Element(nameof(LocationSettings).ToLowerInvariant());

var serializer = new XmlSerializer(typeof(LocationSettings));
var tt = serializer.Deserialize(locationSettingsElement!.CreateReader()) as LocationSettings;

Of course there are some null checks to be handled.