2012-02-10 8 views
2

私はさまざまなクライアントから複数のXSDを取得しており、提供したXSDに準拠したXML形式のデータを提供する必要があります。私は既に、コード化されたSystem.Reflectionとcodeproviderを使用して、XSDからクラスを動的に作成してコンパイルするコードを作成しました。 私の計画は、複数のクエリを通じてデータベースからデータを取得し、フィールドを作成した動的クラスのプロパティにマップしてシリアル化することです。私はこれらのフィールドをマッピングする一般的な方法を探しています。これらのフィールドは、どのタイプのxsdでも使用でき、フィールドをマッピングするだけでシリアル化され、XMLファイルが得られます。クエリに関しては、私はそれらをconfigファイルに入れています。一般的なソリューションは可能ですか?どのようにそれについて行くすべてのアイデアやポインター?実行時に作成されたクラスをシリアライズ

答えて

1

これを解決できました。ここでは、私が使用した手順を示します。まず、リフレクションを使用してxsdから直列化可能な属性を持つcodedom.compilerを使用してインメモリの実行時アセンブリを作成しました。リフレクションを使用して、そのアセンブリ内のクラスのインスタンスを作成し、データベースから取得したデータのプロパティを割り当てました。直列化する別のメソッドに転送したこのクラスはオブジェクトをとり、それをxmlにシリアル化します。

は限りマッピングとして、私は、データベースの列名がXML属性名と一致する必要があることを確認しましたし、それを私ができるマップだったし、それらを呼び出します。ここで

は抜粋です:

object fxClass = myAssembly.CreateInstance(cls.FullName); 
Type t = fxClass.GetType(); 


var arrRates = Array.CreateInstance(t, tab.Rows.Count); 
int i =0; 
foreach (DataRow dr in tab.Rows) 
{ 
    fxClass = myAssembly.CreateInstance(cls.FullName); 
    PropertyInfo[] fxRateProperties = t.GetProperties(); 
    foreach (PropertyInfo prop in fxRateProperties) 
    { 
     string rowVal = dr[prop.Name].ToString(); 

     if (prop.PropertyType == typeof(DateTime)) 
     { 
      prop.SetValue(fxClass, util.convertToDate(rowVal), null); 
     } 
     else if (prop.PropertyType == typeof(bool)) 
     { 
      prop.SetValue(fxClass, util.convertToBoolean(rowVal), null); 
     } 
     else if (prop.PropertyType == typeof(decimal)) 
     { 
      prop.SetValue(fxClass, util.convertToDecimal(rowVal), null); 
     } 
     else prop.SetValue(fxClass, rowVal, null);           
    } 
    arrRates.SetValue(fxClass,i); 
    i++; 
} 
myClass.GetType().GetProperty("ForexRates").SetValue(myClass, arrRates, null); 

は、それから、今、私はどこUI部品を追加する予定です、オブジェクト型を受け入れ、それがこのために

public void serializeXML(object portfolio, string xmlPath) 
{ 
    XmlSerializer serial = new XmlSerializer(portfolio.GetType()); 
    XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); 
    ns.Add("", ""); 
    try 
    { 
     using (FileStream fs = new FileStream(xmlPath, FileMode.Create, FileAccess.Write)) 
     { 
      using (XmlTextWriter tw = new XmlTextWriter(fs, Encoding.UTF8)) 
      { 
       tw.Formatting = Formatting.Indented; 
       serial.Serialize(tw, portfolio, ns); 
      } 
     } 
    } 
} 

のメソッドをシリアル化するMyClassのオブジェクトを渡します"ForexRates"のようなマッピングがデータベースに保存され、次にxsdタイプのいずれかに開きます。あなたの応答のための非常に多くの

感謝。一時的な動的アセンブリがアクセス可能であるように

0

オンザフライで作成されたクラスは、通常の方法ではなく、少なくとも直列化できません。 Serializable属性をアタッチする方法が見つかったとしても、それは効果がありません。つまり、シリアライズアセンブリは生成されません。

理論的には全く新しいクラスを実行時に実行することができますが、それは絶対的な痛みです。これを行うなら、私はMono.Cecilを.NET FrameworkのデフォルトのILエミッタに推奨したいと思います。

+1

シリアライゼーションアセンブリがあれば絶対に必要というわけではない([参考](http://stackoverflow.com/questions/926919/serialization-assembly-is-it-needed-or-not )) –

関連する問題