2010-03-04 39 views
1

我有包含我想反序列化到C#以下格式的XML的Stream對象爲什麼XmlReader將名稱空間uris附加到每個元素?

<?xml version="1.0" encoding="utf-8" standalone="yes"?> 
<OrganisationMetaData xmlns="urn:organisationMetaDataSchema"> 
    <Organisations> 
    <Organisation> 
     <Code>XXX</Code> 
     <Name>Yyyyyy</Name>... 

我做這個負載與串倍,但與流是好心附加的命名空間屬性到所有複雜的元素。如果我只是刪除了xmlns屬性,而忘記了根據模式對它進行驗證,它只會附加一個空的xmlns屬性。我遇到的問題是XmlSerializer(?)中的Deserialize方法會拋出一個錯誤,指出它不指望該屬性。我嘗試用XmlRoot和XmlType屬性裝飾類,但是這並沒有改變任何東西。

這是我想反序列化到

[XmlRoot(
    ElementName = "OrganisationMetaData", 
    Namespace = "urn:organisationMetaDataSchema")] 
public class OrganisationMetaData 
{ 
    public List<Organisation> Organisations { get; set; } 
} 

[XmlType(
    TypeName = "Organisation", 
    Namespace = "urn:organisationMetaDataSchema")] 
public class Organisation 
{ 
    public string Code {get; set;} 

    public string Name {get; set;} 
} 

這裏類的正在使用做的工作

public IList<Organisation> DeserializeOrganisations(Stream stream) 
    { 
     var serializer = new XmlSerializer(typeof(OrganisationMetaData)); 

     var mappingAssembly = //Resource in another assembly 

     var schemas = new XmlSchemaSet(); 
     schemas.Add(
      "urn:organisationMetaDataSchema", 
      XmlReader.Create(
       mappingAssembly.GetManifestResourceStream(
        // An xml schema 
        ) 
       ) 
      ); 
     var settings = new XmlReaderSettings() 
          { 
           ValidationType = ValidationType.Schema, 
           Schemas = schemas, 
           ValidationFlags = 
        XmlSchemaValidationFlags.ReportValidationWarnings 
          };    

     settings.ValidationEventHandler += settings_ValidationEventHandler; 
     var reader = XmlReader.Create(stream, settings); 

     var metaData= (OrganisationMetaData)serializer.Deserialize(reader); 
     return metaData.Organisations.ToList(); 
    } 

我已經試過這一點使用的DataContractSerializer方法,但帶來它自己的[商機學習,所以如果任何人都可以幫助我應該把屬性放在XmlSerializer的屬性上,那就太好了。

任何幫助,將不勝感激,謝謝。

回答

0

我最終改變使用數據契約的代碼序列化程序,它給了我更多關於命名空間的明顯錯誤,使我可以讓讀者根據模式驗證xml流,然後倒回流並在另一個讀取器中重新使用它來反序列化xml。

閱讀this question提醒我一個需要xml元素按字母順序排列的漏洞。我還發現,當反序列化我的類的屬性是一個枚舉時,我需要要求它存在(畢竟它不是空的)。

然後,這導致了另一個錯誤,我有一個xml節點,省略了一些值(由我的模式確定),但數據協定期望這些按順序排列,因此我必須明確指定。

我結束了一個數據成員屬性這樣

[DataMember(
     Name = "MyEnumType", 
     EmitDefaultValue = false, 
     IsRequired = true, 
     Order = 3)] 
//Just assume I added this prop after my Code, and Name properties from above 

感謝馬克抽出時間來看看這個。

1

這裏的關鍵是[XmlRoot]只能應用於根類型,如類;如果您使用的是List<>作爲根目錄,則不起作用 - 但我們可以通過[XmlElement]來補足。我使用的是Stream方法(通過Encoding.UTF8),但請注意,這不是真正的問題的心臟IMO(根類型):

[XmlRoot(Namespace="urn:organisationMetaDataSchema")] 
public class Organisations 
{ 
    private readonly List<Organisation> items = new List<Organisation>(); 
    [XmlElement("Organisation")] 
    public List<Organisation> Items { get { return items; } } 

} 
public class Organisation 
{ 
    public string Code { get; set; } 
    public string Name { get; set; } 
} 
static class Program 
{ 
    static void Main() 
    { 
     string xml = @"<?xml version='1.0' encoding='utf-8' standalone='yes'?><Organisations xmlns='urn:organisationMetaDataSchema'><Organisation><Code>XXXX</Code><Name>YYYYYYYY</Name></Organisation></Organisations>"; 
     XmlSerializer ser = new XmlSerializer(typeof(Organisations)); 
     using (Stream input = new MemoryStream(Encoding.UTF8.GetBytes(xml))) 
     { 
      Organisations orgs = (Organisations)ser.Deserialize(input); 
     } 
    } 
} 
+0

謝謝馬克,我現在對此有點腦衰。我的xml沒有你的字符串所具有的單引號。你將如何克服這個,像Replace(...)這樣簡單的事情? – 2010-03-04 12:24:59

+0

我已經嘗試過所有我能想到的東西,所以大約8個小時後,我已經放棄了DataContractSerializer,而在東方可以告訴我更多關於xml不喜歡的內容。感謝您的幫助Marc :) – 2010-03-04 15:04:25

+0

@Mark - 單引號無關緊要。發佈的代碼應該反序列化你引用的xml。你可以發佈(或電子郵件,如果你喜歡)你的課程?我很確定我可以告訴你什麼是錯的... – 2010-03-04 16:34:26

相關問題