【问题标题】:During C# deserialization, getting System.InvalidOperationException: < xmlns=''> was not expected在 C# 反序列化期间,不期望得到 System.InvalidOperationException: < xmlns=''>
【发布时间】:2016-12-26 20:50:09
【问题描述】:

我是 XML 反序列化的新手。我使用 xsd.exe 生成对象类以对现有 XML 文件执行反序列化。当我在下面运行我的解决方案时,我收到错误

System.InvalidOperationException: 不是预期的

关于“s = (NewDataSet)xs.Deserialize(sr)”调用。我在 Stackoverflow 上查看了这个错误,每个人都说它在 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>

【问题讨论】:

  • 老实说,我在反序列化 xml 时去掉了命名空间以避免这个问题。
  • 我最初是这样做的(在 XmlRootAttribute 中删除了 Namespace=""),但这并没有帮助。我不确定为什么 xsd.exe 会首先尝试包含它。但显然错误 是指命名空间问题。我同意那里。但是什么命名空间? XML 数据文件没有。
  • Dr Dobbs Journal drdobbs.com/windows/parsing-xml-files-in-net-using-c/184416669 中的文章讨论了 5 种方法来做到这一点(包括使用 LINQ),但我正在尝试使用“方法 4”,它在这里使用 XML 反序列化。是的,我知道还有 6 种其他有效方法。

标签: c# xml-parsing xml-deserialization xsd.exe


【解决方案1】:

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

【讨论】:

  • 那么该代码是如何解决问题的呢?甚至解决错误?
  • 我的代码有效。序列化有很多属性,早在2016年就没有试图找出根本原因。序列化很慢,linq很快。几个月前,一个 OP 比较了花费超过 20 秒的序列化和立即返回数据的 xml linq。序列化类是使用 xsd.exe 从架构中生成的。
【解决方案2】:

我开始思考... 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 数据文件生成的代码解决方案作为指导,而不是事实。这是一个很棒的工具,但需要与一粒盐一起使用。 ...欢迎您的 cmets 解决我的 XML 反序列化问题。

【讨论】:

    猜你喜欢
    • 2018-08-28
    • 2021-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多