代码之家  ›  专栏  ›  技术社区  ›  devuxer

为什么必须删除xmlns属性来反序列化XML文件?

  •  4
  • devuxer  · 技术社区  · 15 年前

    问题

    我在用 Xsd2Code (用于XSD架构的.NET类生成器)在简单设置文件架构上。出于某种原因,当我尝试使用内置的 LoadFromFile() Deserialize() 方法,我得到一个异常,它似乎与 xmlns 我的XSD和XML文件中的属性。如果删除这些属性,异常就会消失。(请看我的) 更新 “下面是有关实际导致异常的代码的详细信息。)


    XSD文件

    <?xml version="1.0" encoding="utf-8"?>
    <xs:schema
      xmlns="Myco.CLDatabaseBuilder.Models"
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      targetNamespace="Myco.CLDatabaseBuilder.Models"
      elementFormDefault="qualified">
      <xs:element name="Settings" type="Settings" />
      <xs:complexType name="Settings">
        <xs:sequence>
          <xs:element name="SqlServerInstanceName" type="xs:string" />
          <xs:element name="DatabaseName" type="xs:string" />
          <xs:element name="RootDatabaseName" type="xs:string" />
        </xs:sequence>
      </xs:complexType>
    </xs:schema>
    

    XML文件(失败) -当我尝试反序列化时,得到一个异常

    <?xml version="1.0" encoding="UTF-8"?>
    <Settings
      xmlns="Myco.CLDatabaseBuilder.Models"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="Myco.CLDatabaseBuilder.Models Settings.xsd">
      <SqlServerInstanceName>SQLEXPRESS</SqlServerInstanceName>
      <DatabaseName>CL</DatabaseName>
      <RootDatabaseName>master</RootDatabaseName>
    </Settings>
    

    XML文件(成功) -反序列化工作正常

    <?xml version="1.0" encoding="UTF-8"?>
    <Settings
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="Myco.CLDatabaseBuilder.Models Settings.xsd">
      <SqlServerInstanceName>SQLEXPRESS</SqlServerInstanceName>
      <DatabaseName>CL</DatabaseName>
      <RootDatabaseName>master</RootDatabaseName>
    </Settings>
    

    异常详细信息 -如果我运行“失败示例”,会发生什么?

    A first chance exception of type 'System.InvalidOperationException' occurred in System.Xml.dll
    System.InvalidOperationException: There is an error in XML document (2, 2). ---> System.InvalidOperationException: <Settings xmlns='Myco.CLDatabaseBuilder.Models'> was not expected.
       at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderSettings.Read3_Settings()
       --- End of inner exception stack trace ---
       at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
       at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader)
       at Myco.CLDatabaseBuilder.Models.Settings.Deserialize(String xml) in C:\...\CLDatabaseBuilder\Models\Settings.cs:line 118
       at Myco.CLDatabaseBuilder.Models.Settings.LoadFromFile(String fileName) in C:\...\CLDatabaseBuilder\Models\Settings.cs:line 195
       at Myco.CLDatabaseBuilder.Program.InitializeSettings() in C:\...\CLDatabaseBuilder\Program.cs:line 68
    

    问题:

    所以基本上,我必须去掉默认的名称空间才能反序列化。

    知道为什么我在使用时会遇到异常吗? XMLNS ? 此命名空间声明对于在Visual Studio中进行实时验证非常有用,因此如果可能,我希望保留它。

    我的xsd根元素属性有问题吗? 我搞砸了 elementFormDefault (从 qualified unqualified 但这并没有解决问题。


    更新

    它实际上阻塞的代码是:

    Serializer = new System.Xml.Serialization.XmlSerializer(typeof(Myco.CDDatabaseBuilder.Models.Settings));
    Serializer.Deserialize(System.Xml.XmlReader.Create(stringReader));
    

    如上面的异常所示,我得到的错误是:

    <Settings xmlns='Myco.CLDatabaseBuilder.Models'> 不是预期的。

    这是否表明在我的 Settings 类(由xsd2code生成的类)?有 [System.Xml.Serialization...] 属性散布在这个类中。我想知道是否缺少了一些东西,或者类(或序列化程序)是否没有建模默认值的方法 XMLNS 属性。有什么好主意吗?

    2 回复  |  直到 15 年前
        1
  •  8
  •   devuxer    15 年前

    有一天…我需要四个小角色。

    XSD2code中有一个开关 /xa+ 那套 GenerateXMLAttributes = true

    出于某种原因,默认值为假。嗯,如果你有一个 xmlns 属性,您需要反序列化。

        2
  •  3
  •   Cheeso    15 年前

    我不知道是什么问题,但它应该起作用。你被迷惑是对的。我通过.NET SDK附带的xsd.exe工具运行了您的架构。它从您的模式生成这个类:

    [XmlType(Namespace="Myco.CLDatabaseBuilder.Models")]
    [XmlRoot(Namespace="Myco.CLDatabaseBuilder.Models", IsNullable=false)]
    public partial class Settings {
    
        private string sqlServerInstanceNameField;
    
        private string databaseNameField;
    
        private string rootDatabaseNameField;
    
        /// <remarks/>
        public string SqlServerInstanceName {
            get {
                return this.sqlServerInstanceNameField;
            }
            set {
                this.sqlServerInstanceNameField = value;
            }
        }
    
        /// <remarks/>
        public string DatabaseName {
            get {
                return this.databaseNameField;
            }
            set {
                this.databaseNameField = value;
            }
        }
    
        /// <remarks/>
        public string RootDatabaseName {
            get {
                return this.rootDatabaseNameField;
            }
            set {
                this.rootDatabaseNameField = value;
            }
        }
    }
    

    正如您所看到的,类中装饰的属性很少。有一个xmltype和一个xmlroot,就是这样。该类中的三个属性都是隐式序列化的,即使没有xmlElement属性。

    我得到的结果 重新 -将XML序列化如下:

    <q1:Settings xmlns:q1="Myco.CLDatabaseBuilder.Models">
      <q1:SqlServerInstanceName>SQLEXPRESS</q1:SqlServerInstanceName>
      <q1:DatabaseName>CL</q1:DatabaseName>
      <q1:RootDatabaseName>master</q1:RootDatabaseName>
    </q1:Settings>