2017-09-11 6 views
0

XML:DeserialisingのXML

<?xml version="1.0" encoding="UTF-8"?> 
<Images> 
    <I0> 
     <Path>123.com</Path> 
    <I0> 
    <I1> 
     <Path>123.com</Path> 
    <I1> 
    <I2> 
     <Path>123.com</Path> 
    <I2> 
</Images> 

がserializer.Deserialize()コレクションに異なる名前のタグを取得するために使用することができますか?

のC#:

現在、私のオブジェクトに私が持っている

public class rootObject 
{ 
    [XmlElement(ElementName = "I0")] 
    public I0 I0 { get; set; } 
    [XmlElement(ElementName = "I1")] 
    public I1 I1 { get; set; } 
    [XmlElement(ElementName = "I2")] 
    public I2 I2 { get; set; } 

} 

しかし、私は(画像はより多くのまたは少ない要素を持つことができるため)持っていると思います:

public class rootObject 
{ 
    public List<I> Is { get; set; } 
} 

答えて

0

ますジェネリックをやっているあなたのクラスの型引数を渡すだけでよいことを示唆しているものを行うことができます。デシリアライゼーションルーチンを実行するときに覚えておくべき重要な点は、ルーチンがサブリファレンスを知る必要があることです。だから、もし私がstringと言うならば、それは爆弾になるだろう。参照文字列を知る必要があります.Deserialize>ここで、Subは変更可能なクラスオブジェクトです。

私は基本クラスを持っていますが、私は 'T'を拡張可能な能力のために後から変更することができます。

[Serializable] 
public class Test<T> where T : class 
{ 
    public Test() { } 

    public int TestId { get; set; } 
    public string Name { get; set; } 
    public List<T> Shipments { get; set; } 
} 

私はちょうど異なる特性がわずかに

[Serializable] 
public class Sub1 
{ 
    public int Id { get; set; } 
    public string Desc { get; set; } 
} 

[Serializable] 
public class Sub2 
{ 
    public int IdWhatever { get; set; } 
    public string DescWhatever { get; set; } 
} 

今度はメインプログラムとテストのシリアル化をやられているという構成する2つのクラスでこれをテストしたいです。

class Program 
{ 
    static void Main(string[] args) 
    { 
     var serializeTest = new Test<Sub1> { TestId = 1, Name = "Test", Shipments = new List<Sub1> { new Sub1 { Id = 1, Desc = "Test" }, new Sub1 { Id = 2, Desc = "Test2" } } }; 
     var serializeTest2 = new Test<Sub2> { TestId = 1, Name = "Test", Shipments = new List<Sub2> { new Sub2 { IdWhatever = 1, DescWhatever = "Test" }, new Sub2 { IdWhatever = 2, DescWhatever = "Test2" } } }; 
     var serialized = serializeTest.SerializeToXml(); 
     var serialized2 = serializeTest2.SerializeToXml(); 
     var deserialized = serialized.DeserializeXml<Test<Sub1>>(); 
     var deserialized2 = serialized2.DeserializeXml<Test<Sub2>>(); 

     Console.WriteLine(serialized); 
     Console.WriteLine(); 
     Console.WriteLine(serialized2); 
     Console.ReadLine(); 
    } 
} 

そして、私のシリアル化と逆シリアル化する拡張メソッド:

public static string SerializeToXml<T>(this T valueToSerialize, string namespaceUsed = null) 
{ 
     var ns = new XmlSerializerNamespaces(new XmlQualifiedName[] { new XmlQualifiedName(string.Empty, (namespaceUsed != null) ? namespaceUsed : string.Empty) }); 
     using (var sw = new StringWriter()) 
     { 
     using (XmlWriter writer = XmlWriter.Create(sw, new XmlWriterSettings { OmitXmlDeclaration = true })) 
     { 
      dynamic xmler = new XmlSerializer(typeof(T)); 
      xmler.Serialize(writer, valueToSerialize, ns); 
     } 

     return sw.ToString(); 
     } 
} 

public static T DeserializeXml<T>(this string xmlToDeserialize) 
{ 
    dynamic serializer = new XmlSerializer(typeof(T)); 

    using (TextReader reader = new StringReader(xmlToDeserialize)) 
    { 
    return (T)serializer.Deserialize(reader); 
    } 
} 
0

あなたは、プロパティがXMLに一致するときのXmlElement名を指定する必要はありません。いくつかのソリューション、いくつかちょっとハッキー:)。

  1. ハック:、 How to deserialize an XML array containing multiple types of elements in C# いますが、I0の属性を追加する必要があるだろう:これはあなたのために働くかもしれない:ややハックちょうど<I></I>
  2. <I#></I#>を置き換えるために置き換える正規表現の文字列を使用します、i1 ... i100など
  3. ベスト:これはXML全体ですか?私は正直なところ、LINQToXmlを使用して Descendants( "Path")を実行し、1行のコードで文字列の配列を取得します。シリアライゼーションは実際にはこのための最良の解決策ではありません。