2010-01-21 33 views
4

問題爲什麼我必須刪除xmlns屬性才能反序列化我的XML文件?

我使用Xsd2Code一個簡單的設置文件架構(.NET類的XSD模式生成)。出於某種原因,當我嘗試使用內置的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屬性的方法。任何想法讚賞。

回答

8

其中一個日子......事實證明我需要四個小角色。

有一個在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屬性也是如此。

結果我從得到重新 -serializing你的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> 
+0

+1所付出的努力,但我居然想通了這個問題(見我的答案)。有趣的是,當你重新序列化時,它會執行'xmlns:q1'而不是僅僅使用默認的命名空間。 – devuxer 2010-01-22 06:12:34

相關問題