-1

I'm new to XMLdeserialization. I used xsd.exe to generate object classes for performing a deserialization on an existing XML file. When I run my solution below, I get the error

System.InvalidOperationException: < xmlns=''> was not expected

on the s = (NewDataSet)xs.Deserialize(sr) call. I looked this error up on Stack Overflow, and everyone says it's in the XMLRootAttribute line.

[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]

How can I correct this line? Or where can I find some documentation that explains how to correct it?

Also, why doesn't xsd.exe generate the correct XmlRootAttribute line in the first place? Am I invoking this utility wrong? Or are there some situations the xsd.exe utility can't handle?

public class Program
{
    static void Main(string[] args)
    {
        SortedSet<string> symbolsEstablished = new SortedSet<string>();

        GetXmlDataSet("Expt 2buy.xml", ref symbolsEstablished);
    }

    public static void GetXmlDataSet(string fileName, ref SortedSet<string> symbols)
    {
        XmlSerializer xs = new XmlSerializer(typeof(NewDataSet));
        StreamReader sr = new StreamReader(@"C:\Users\mehl\AppData\Roaming\Fidelity Investments\WealthLabPro\1.0.0.0\Data\DataSets\" + fileName);
        NewDataSet s = (NewDataSet)xs.Deserialize(sr);
        Console.WriteLine(s.Items[0].DSString);
        sr.Close();
    }

    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
    public partial class DataSet
    {
        private string nameField;
        private string scaleField;
        private string barIntervalField;
        private string dSStringField;
        private string providerNameField;

        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Name
        {
            get { return this.nameField; }
            set { this.nameField = value; }
        }

        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Scale
        {
            get { return this.scaleField; }
            set { this.scaleField = value; }
        }

        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string BarInterval
        {
            get { return this.barIntervalField; }
            set { this.barIntervalField = value; }
        }

        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string DSString
        {
            get { return this.dSStringField; }
            set { this.dSStringField = value; }
        }

        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string ProviderName
        {
            get { return this.providerNameField; }
            set { this.providerNameField = value; }
        }
    }

    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
    public partial class NewDataSet
    {
        private DataSet[] itemsField;

        [System.Xml.Serialization.XmlElementAttribute("DataSet")]
        public DataSet[] Items
        {
            get { return this.itemsField; }
            set { this.itemsField = value; }
        }
    }
}

The entire above code segment is wrapped in a screener2wl namespace.

And here's the XML file I'm trying to deserialize:

<?xml version="1.0"?>
<DataSet xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Name>Expt 2buy</Name>
  <Scale>Daily</Scale>
  <BarInterval>0</BarInterval>
  <DSString>AAL,AFSI,BEN,BIG,BLKB,CDK,COHR,CRUS,EGP,EPE,ETH,FB,HUM,LSTR,MDP,MSI,NYT,TAST,TER,TSO,TXN,UTHR,VASC,VLO,WRI,</DSString>
  <ProviderName>FidelityStaticProvider</ProviderName>
</DataSet>
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
  • Honestly, I strip out namespaces when deserializing xml to avoid this problem. – P. Roe Dec 26 '16 at 22:08
  • I originally did that (stripped out Namespace="" in the XmlRootAttribute), but that didn't help. I'm not sure why xsd.exe tries to include it in the first place. But clearly the error < xmlns=''> is referring to namespace issues. I agree there. But what namespace? The XML data file doesn't have any. – superticker Dec 26 '16 at 23:15
  • The article in Dr Dobbs Journal http://www.drdobbs.com/windows/parsing-xml-files-in-net-using-c/184416669 discusses 5 methods to do this (including using LINQ), but I'm trying to employ "Method 4", which uses XMLdeserialization here. Yes, I know there are 6 other valid methods. – superticker Dec 26 '16 at 23:20

2 Answers2

1

Using xml linq :

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

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            DataSet ds = doc.Descendants("DataSet").Select(x => new DataSet() {
                nameField = (string)x.Element("Name"),
                scaleField = (string)x.Element("Scale"),
                barIntervalField = (string)x.Element("BarInterval"),
                dSStringField = (string)x.Element("DSString"),
                providerNameField = (string)x.Element("ProviderName")
            }).FirstOrDefault();
        }
    }
    public partial class DataSet
    {
        public string nameField { get; set; }
        public string scaleField { get; set; }
        public string barIntervalField { get; set; }
        public string dSStringField { get; set; }
        public string providerNameField { get; set; }
    }
}
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • So how does that code resolve the issue? Or even address the error? – Suncat2000 Mar 11 '20 at 14:50
  • My code works. There are lots of attributes in the serialization and did not try to figure out the root cause back in 2016. Serialization is very slow and linq is very fast. A couple of months ago one OP compared the serialization which was taking over 20 seconds and with xml linq which returned data immediately. The serialization classes were generated with xsd.exe from a schema. – jdweng Mar 11 '20 at 15:20
0

I got to thinking ... isn't it odd xsd.exe would provide a code generated solution that defines two independent XmlRootAttribute nodes? Can an XML file even have two Root Nodes? Maybe the solutions xsd.exe generates shouldn't be taken too literally. :-)

So after editing its solution, and removing one part with a second XmlRootAttribute defined, I got the solution below, which works.

namespace screener2wl
{
    public class Program
    {
        static void Main(string[] args)
        {
            SortedSet<string> symbolsEstablished = new SortedSet<string>();
            GetXmlDataSet("Expt 2buy.xml", ref symbolsEstablished);
        }

        public static void GetXmlDataSet(string fileName, ref SortedSet<string> symbols)
        {
            XmlSerializer xs = new XmlSerializer(typeof(DataSet));
            StreamReader sr = new StreamReader(@"C:\Users\mehl\AppData\Roaming\Fidelity Investments\WealthLabPro\1.0.0.0\Data\DataSets\" + fileName);
            DataSet s = (DataSet)xs.Deserialize(sr);
            Console.WriteLine(s.DSString);
            sr.Close();
        }

        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
        [System.Xml.Serialization.XmlRootAttribute(IsNullable = false)]
        public class DataSet
        {
            private string nameField;
            private string scaleField;
            private string barIntervalField;
            private string dSStringField;
            private string providerNameField;

            [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
            public string Name
            {
                get { return this.nameField; }
                set { this.nameField = value; }
            }

            [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
            public string Scale
            {
                get { return this.scaleField; }
                set { this.scaleField = value; }
            }

            [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
            public string BarInterval
            {
                get { return this.barIntervalField; }
                set { this.barIntervalField = value; }
            }

            [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
            public string DSString
            {
                get { return this.dSStringField; }
                set { this.dSStringField = value; }
            }

            [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
            public string ProviderName
            {
                get { return this.providerNameField; }
                set { this.providerNameField = value; }
            }
        }
    }
}

Bottom line, use the code solutions xsd.exe generates from your XML data file as a guide, not a truth. It's a great tool, but needs to be used with a grain of salt. ... welcome your comments on my XMLdeserialization problem.