2017-05-09 9 views
3

XML文字列をListに変換する必要があります。メソッドは汎用である必要があります。私は方法を書いたが、期待通りの性能を発揮していない。C#の要素ルートを指定せずにXML文字列をリスト<T>に変換します。

シナリオ:#1

モデルクラス:

public class Employee { 
    public int EmpId { get; set; } 
    public string Name { get; set; } 
} 

XML:

<EmployeeList 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Employee> 
     <EmpId>1</EmpId> 
     <Name>Emma</Name> 
    </Employee> 
    <Employee> 
     <EmpId>2</EmpId> 
     <Name>Watson</Name> 
    </Employee> 
</EmployeeList> 

シナリオ:#2

モデルクラス:

public class Person { 
    public int PersonId { get; set; } 
    public string Name { get; set; } 
} 

XML:私は上記の変換する一般的な方法を必要とする

<PersonList 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Person> 
     <PersonId>1</EmpId> 
     <Name>Emma</Name> 
    </Person> 
    <Person> 
     <PersonId>2</EmpId> 
     <Name>Watson</Name> 
    </Person> 
</PersonList> 

List<Employee>List<Person>へのXMLの言いました。

私は、次のコード

public static T[] ParseXML<T>(this string @this) where T : class { 
    var reader = XmlReader.Create(@this.Trim().ToStream(),new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document }); 
    return new XmlSerializer(typeof(T[])).Deserialize(reader) as T[]; 
} 

を使用しかし、私はNULLを取得しています。親切に私の手助けをしてください。

私はたくさんのコードを審査しましたが、ルート要素をハードコードされた値として指定するように指示しています。しかし、私は一般的な方法が必要です。

署名が

public static T[] ParseXML<T>(this string @this) where T : class { } 

親切にこの点で私を支援する必要があります。

答えて

2

あなたはシリアライザを指示する必要がありますので、デフォルトのルート名は、ArrayOfThing、ないThingListです:

var ser = new XmlSerializer(list.GetType(), new XmlRootAttribute("EmployeeList")); 

はしかし、あなたはまた、(組立メモリリークを防ぐために、これをキャッシュし、再使用する必要があります最も基本的なコンストラクタだけが自動的にキャッシュされます)。ジェネリック型の静的な読み取り専用フィールドには、例えば、良い賭けです:

static class SerializerCache<T> { 
    public static readonly XmlSerializer Instance = new XmlSerializer(
     typeof(List<T>), new XmlRootAttribute(typeof(T).Name + "List")); 
} 

あなたが好きなら明らか

+0

@Masteroのように見えている。そこに必要な変更なし - 'のちょうど最後の行ParseXML'は 'SerializerCache .Instance'の代わりに' new XmlSerializer(...) ' –

+0

はい私はそれを得た。ありがとう... –

0

...リストと配列を入れ替える代わりにnew XmlSerializer

SerializerCache<T>.Instanceを使用します私はMarc Gravell - Convert XML string to List<T> without specifiying Element Root in C#の答えを得ました。これは正しいとマークされています。

public static class SerializerCache<T> { 
    public static readonly XmlSerializer Instance = new XmlSerializer(
     typeof(List<T>), new XmlRootAttribute(typeof(T).Name + "List")); 
} 

public static class XMLHelper { 

    public static List<T> ParseXML<T>(this string @this) where T : class { 

     XmlSerializer serializer = SerializerCache<T>.Instance; 
     MemoryStream memStream = new MemoryStream(Encoding.UTF8.GetBytes(@this)); 

     if(!string.IsNullorEmpty(@this) && (serializer != null) && (memStream != null)) { 
      return serializer.Deserialize(memStream) as List<T>; 
     } 
     else { 
      return null; 
     } 
    } 
} 

主な方法は、私が述べてきたすべてがそう、既存の `ParseXML`方法、*内側*どうなる

public static List<Employee> GetEmployeeList(string xml) { 
    return xml.ParseXML<Employee>(); 
} 
関連する問題