【问题标题】:Why must I remove the xmlns attribute to deserialize my XML file?为什么我必须删除 xmlns 属性才能反序列化我的 XML 文件?
【发布时间】:2010-01-22 10:53:18
【问题描述】:

问题

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


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

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

&lt;Settings xmlns='Myco.CLDatabaseBuilder.Models'&gt; 不是预期的。

这是否表明在我的 Settings 类(由 Xsd2Code 生成的类)中寻找任何东西?整个班级都有[System.Xml.Serialization...] 属性。我想知道是否缺少某些东西,或者该类(或序列化程序)是否无法对默认的 xmlns 属性进行建模。任何想法表示赞赏。

【问题讨论】:

    标签: c# xml serialization xsd xml-serialization


    【解决方案1】:

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

    Xsd2Code 中有一个开关/xa+ 设置GenerateXMLAttributes = true

    出于某种原因,默认值为 false。好吧,如果你有一个 xmlns 属性并且你想反序列化,它必须是真的。

    【讨论】:

      【解决方案2】:

      我不知道问题出在哪里,但应该可以。你感到困惑是对的。我通过 .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 属性。

      我从 re 序列化你的 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>
      

      【讨论】:

      • 为努力+1,但我实际上发现了问题(请参阅我的答案)。有趣的是,当您重新序列化时,它会使用 xmlns:q1 而不仅仅是使用默认命名空间。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-21
      • 2011-11-15
      • 1970-01-01
      • 2020-02-13
      • 1970-01-01
      • 2020-08-28
      相关资源
      最近更新 更多