Во время десериализации C# получение System.InvalidOperationException: <xmlns = ''> не ожидалось

Я новичок в XML-десериализации. Я использовал xsd.exe для генерации классов объектов для выполнения десериализации существующего XML-файла. Когда я запускаю свое решение ниже, я получаю ошибку

System.InvalidOperationException: не ожидалось

по вызову " s = (NewDataSet) xs.Deserialize (sr) ". Я посмотрел эту ошибку в Stackru, и все говорят, что она находится в строке XMLRootAttribute.

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

Я пробовал все виды исправлений в этой строке, но ничего не работает. Может кто-нибудь исправить это или указать мне документацию, которая объясняет, как это исправить? Большое спасибо заранее.

Кроме того, почему xsd.exe не генерирует правильную строку XmlRootAttribute? Я неправильно вызываю эту утилиту? Или в каких ситуациях утилита xsd.exe не может справиться?

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; }
        }
    }
}

Весь приведенный выше фрагмент кода обернут в пространство имен screener2wl.

И вот файл XML, который я пытаюсь десериализовать:

<?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>

2 ответа

Использование 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; }
    }
}

Я подумал... разве не странно, что xsd.exe обеспечит решение, сгенерированное кодом, которое определяет два независимых узла XmlRootAttribute? Может ли файл XML иметь два корневых узла? Возможно, решения, которые генерирует xsd.exe, не следует воспринимать слишком буквально.:-)

Таким образом, после редактирования своего решения и удаления одной части со вторым определенным атрибутом XmlRootAttribute, я получил решение ниже, которое работает.

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; }
            }
        }
    }
}

В итоге, используйте код, который xsd.exe генерирует из вашего файла данных XML, в качестве руководства, а не правды. Это отличный инструмент, но его нужно использовать с небольшим количеством соли.... приветствую ваши комментарии по моей проблеме XML-десериализации.

Другие вопросы по тегам