2016-07-22 10 views
3

XMLデータの文字列を逆シリアル化しようとしています。しかし、デシリアライズ関数によって返されたオブジェクトにはデータは返されません。ここでクラス内の配列によるXMLの逆シリアル化

は、クラス定義されている:ここで

[XmlType("STATE-COUNTY-RECORDS")] 
public class StateCountyRecords 
{ 
    [XmlElement("TOTAL")] 
    public int Total { get; set; } 

    [XmlElement("LIMIT")] 
    public int Limit { get; set; } 

    [XmlElement("OFFSET")] 
    public int Offset { get; set; } 

    [XmlArray("STATE-COUNTY-ARRAY"), XmlArrayItem("STATE-COUNTY")] 
    public StateCounty[] StateCountyArray { get; set; } 

    public StateCountyRecords() {} 

    public StateCountyRecords(int total, int limit, int offset, int[] id, string[] fips_code, string[] state, string[] name) 
    { 
     Total = total; 
     Limit = limit; 
     Offset = offset; 

     var count = id.Length; 
     StateCountyArray = new StateCounty[count]; 
     for (int i = 0; i < count; i++) 
     { 
      StateCountyArray[i] = new StateCounty(id[i], fips_code[i], state[i], name[i]); 
     } 
    } 
} 

public class StateCounty 
{ 
    [XmlElement("ID")] 
    public int Id { get; set; } 

    [XmlElement("FIPS-CODE")] 
    public string Fips_Code { get; set; } 

    [XmlElement("STATE")] 
    public string State { get; set; } 

    [XmlElement("NAME")] 
    public string Name { get; set; } 

    public StateCounty(int id, string fips_code, string state, string name) 
    { 
     Id = id; 
     Fips_Code = fips_code; 
     State = state; 
     Name = name; 
    } 

    public StateCounty() { } 
} 

は、XML文字列データである:ここで

<?xml version=\"1.0\" encoding=\"UTF-8\"?> 
<STATE-COUNTY-FILE xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"> 
<STATE-COUNTY-RECORDS> 
    <TOTAL>3314</TOTAL> 
    <LIMIT>10</LIMIT> 
    <OFFSET>0</OFFSET> 
    <STATE-COUNTY-ARRAY> 
    <STATE-COUNTY> 
     <ID>1</ID> 
     <FIPS-CODE>01000</FIPS-CODE> 
     <STATE>AL</STATE> 
     <NAME>Alabama</NAME> 
    </STATE-COUNTY> 
    <STATE-COUNTY> 
     <ID>2</ID> 
     <FIPS-CODE>01001</FIPS-CODE> 
     <STATE>AL</STATE> 
     <NAME>Autauga</NAME> 
    </STATE-COUNTY> 
    <STATE-COUNTY> 
     <ID>3</ID> 
     <FIPS-CODE>01003</FIPS-CODE> 
     <STATE>AL</STATE> 
     <NAME>Baldwin</NAME> 
    </STATE-COUNTY> 
    </STATE-COUNTY-ARRAY> 
</STATE-COUNTY-RECORDS> 
</STATE-COUNTY-FILE> 

は、XML文字列をデシリアライズする機能です。

public static StateCountyRecords DeserializeStateCountyData(string xmlString) 
    { 
     XmlSerializer mySerializer = new XmlSerializer(typeof(StateCountyRecords), new XmlRootAttribute("STATE-COUNTY-FILE")); 
     using (XmlReader myXmlReader = XmlReader.Create(new StringReader(xmlString))) 
     { 
      StateCountyRecords rslt; 
      rslt = (StateCountyRecords)mySerializer.Deserialize(myXmlReader); 
     } 
    } 
} 

RSLT私は戻って、合計と限界、およびオフセットがすべて0であり、StateCountyArrayがnullであるデータを含んでいないことがわかった。私は何の誤りもなかった。私のクラス定義ののXmlElementとXMLファイルとの間に不一致がある場合、私は疑問に思う

if (myXmlReader.CanResolveEntity && myXmlReader.CanReadValueChunk && myXmlReader.CanReadBinaryContent) 
       rslt = (StateCountyRecords)mySerializer.Deserialize(myXmlReader); 

:私はすることで、XMLが有効であることを確認しました。

+0

あなたの質問は何ですか? – Ares

+0

xmlを修正しました。 –

+0

StateCountyクラスのXmlTypeアノテーションはありません。私は '[XmlType(" STATE-COUNTY ")]'の行に沿って何かを見たいと思うでしょう。構造体からいくつかのサンプルXMLを出力するためのシリアライゼーションコードを記述し、すべてのデータが格納されたテストオブジェクトを使用すると、現在のXMLと比較して、ここで何がうまくいかないのかが分かります。 – ManoDestra

答えて

1

あなたの問題は、あなたのXMLは、データモデル、すなわち<STATE-COUNTY-FILE>要素に計上されていない外側の要素があることである:あなたのデータモデルのルートが対応は何もありませんStateCountyRecordsあるので

<STATE-COUNTY-FILE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <STATE-COUNTY-RECORDS> 
    <!-- Various elements under StateCountyRecords --> 
    </STATE-COUNTY-RECORDS> 
</STATE-COUNTY-FILE> 

をこの最も外側の要素に。 new XmlRootAttribute("STATE-COUNTY-FILE")を使用してこれを解決しようとしますが、外部要素の名前を変更するだけで、追加レベルの入れ子を追加することはありません。次のように

[XmlType("STATE-COUNTY-FILE")] 
public class StateCountyFile 
{ 
    [XmlElement("STATE-COUNTY-RECORDS")] 
    public StateCountyRecords StateCountyRecords { get; set; } 
} 

そしてデシリアライズ:

public static StateCountyRecords DeserializeStateCountyData(string xmlString) 
    { 
     var mySerializer = new XmlSerializer(typeof(StateCountyFile)); 
     using (var myXmlReader = XmlReader.Create(new StringReader(xmlString))) 
     { 
      var rslt = (StateCountyFile)mySerializer.Deserialize(myXmlReader); 
      return rslt.StateCountyRecords; 
     } 
    } 

を別の方法としては、手動で要素に遭遇するまでXmlReaderを進めることができ、

は代わりに、あなたは、この目的のために外容器POCOを導入する必要があります<STATE-COUNTY-RECORDS>という名前を付けて、それを逆シリアル化します。

public static StateCountyRecords DeserializeStateCountyData(string xmlString) 
    { 
     return XmlTypeExtensions.DeserializeNestedElement<StateCountyRecords>(xmlString); 
    } 

使用拡張メソッド:

public static class XmlTypeExtensions 
{ 
    public static T DeserializeNestedElement<T>(string xmlString) 
    { 
     var mySerializer = new XmlSerializer(typeof(T)); 
     var typeName = typeof(T).XmlTypeName(); 
     var typeNamespace = typeof(T).XmlTypeNamespace(); 

     using (var myXmlReader = XmlReader.Create(new StringReader(xmlString))) 
     { 
      while (myXmlReader.Read()) 
       if (myXmlReader.NodeType == XmlNodeType.Element && myXmlReader.Name == typeName && myXmlReader.NamespaceURI == typeNamespace) 
       { 
        return (T)mySerializer.Deserialize(myXmlReader); 
       } 
      return default(T); 
     } 
    } 

    public static string XmlTypeName(this Type type) 
    { 
     var xmlType = type.GetCustomAttribute<XmlTypeAttribute>(); 
     if (xmlType != null && !string.IsNullOrEmpty(xmlType.TypeName)) 
      return xmlType.TypeName; 
     return type.Name; 
    } 

    public static string XmlTypeNamespace(this Type type) 
    { 
     var xmlType = type.GetCustomAttribute<XmlTypeAttribute>(); 
     if (xmlType != null && !string.IsNullOrEmpty(xmlType.Namespace)) 
      return xmlType.Namespace; 
     return string.Empty; 
    } 
} 

。なお、このようなデシリアライゼーションの問題が容易に、入力XMLで得られたXMLを比較し、それをシリアライズ、メモリ内のクラスのインスタンスを作成することによって診断されます。通常、問題は明らかです。

関連する問題