问题
我在简单的设置文件架构上使用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));
如上面的例外情况所示,我得到的错误是:
<Settings xmlns='Myco.CLDatabaseBuilder.Models'>
没有预料到。
这是否表明在我的Settings
类(由Xsd2Code生成的类)中要查找的内容?本课程中有[System.Xml.Serialization...]
个属性。我想知道是否缺少某些内容,或者类(或序列化程序)是否无法对默认的xmlns
属性进行建模。任何想法都赞赏。
答案 0 :(得分:8)
其中一天......结果我需要四个小角色。
Xsd2Code /xa+
中有一个设置GenerateXMLAttributes = true
由于某种原因,默认值为false。好吧,如果你有一个xmlns
属性并且想要反序列化,那么它必须是真的。
答案 1 :(得分:3)
我不知道问题是什么,但应该有效。你很困惑。我通过.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>