2017-02-09 13 views
2

私は多くのXMLスキーマ最も効率的な方法は、クラスの使用は、XMLデシリアライズする方法を決定するために

XML 1.0のための多くの.xsdファイルを持っている - xml_1_0.xml

<?xml version="1.0" encoding="UTF-8"?> 
    <cars version="1.00"> 
     <car>Honda</car> 
     <car>Ferrari</car> 
    </cars> 

XMLを2.0 - xml_2_0.xml

<?xml version="1.0" encoding="UTF-8"?> 
<cars version="2.00"> 
    <car> 
     <name>Honda</name> 
     <color>White</color> 
    </car> 

    <car> 
     <name>Honda</name> 
     <color>Red</color> 
    </car> 
</cars> 

私はこの

xsd.exe cars_1_0.xsd /c 

xsd.exe cars_2_0.xsd /c 

よう.XSDから私のクラスを作成し、このようにデシリアライズ:

foreach(string file in files) { 
    XmlDocument doc = new XmlDocument(); 
    doc.Load(file);  
    string version = doc.SelectSingleNode("/Cars/@version").Value; 

    if(version == "1.00") 
    { 
     Stream reader = new FileStream(file, FileMode.Open); 
     XmlSerializer serializer = new XmlSerializer(typeof(v1.Cars)); 

     v1.Cars XML = new v1.Cars(); 
     XML = (v1.Cars)serializer.Deserialize(reader); 
    } 
    else if(version == "2.00") 
    { 
     Stream reader = new FileStream(file, FileMode.Open); 
     XmlSerializer serializer = new XmlSerializer(typeof(v2.Cars)); 

     v2.Cars XML = new v2.Cars(); 
     XML = (v2.Cars)serializer.Deserialize(reader); 
    } 
} 

誰もがこれを行うには良い方法を知っている、またはより優れた性能を持っていますか?

+0

実際のXSDを共有できますか? XSDをオプションに変更していますか?新しいクラスを作成するオプションですか? –

+0

質問に私はちょうど例を書いた、xsdファイルははるかに複雑であり、xmlのどんなバージョンも多くの他の属性を持っています –

答えて

1

あなたはこれをどれくらい遠くにしたいかによって、いくつかの選択肢があります。かなり非侵襲的なオプションの1つは、XmlDocumentを使用せず、ストリームを複数回読み込まないようにすることです。あなただけのルート要素オフ読んでいるので、あなたもXmlReaderなくリセットする必要がありますから、デシリアライズして逃げることができるかもしれません

foreach (string file in files) 
{ 
    using (var stream = new FileStream(file, FileMode.Open)) 
    { 
     var settings = new XmlReaderSettings(); 
     settings.CloseInput = false; 
     string version = ""; 
     using (var xmlReader = XmlReader.Create(stream)) 
     { 
      if (xmlReader.ReadToFollowing("Cars")) 
      { 
       version = xmlReader.GetAttribute("version"); 
      } 
      else 
      { 
       throw new XmlException("Could not get 'version' attribute of 'Cars' root element!"); 
      }      
     } 
     stream.Position = 0; 
     if (version == "1.00") 
     { 
      XmlSerializer serializer = new XmlSerializer(typeof(v1.Cars)); 

      v1.Cars XML = new v1.Cars(); 
      XML = (v1.Cars)serializer.Deserialize(stream); 
     } 
     else if (version == "2.00") 
     { 
      XmlSerializer serializer = new XmlSerializer(typeof(v2.Cars)); 

      v2.Cars XML = new v2.Cars(); 
      XML = (v2.Cars)serializer.Deserialize(stream); 

     } 
    } 
} 

:たとえば、既存のコードがに/合理化簡素化することができFileStreamの位置。

これにより、ファイル全体を2回読み込むオーバーヘッドを回避します(XmlDocumentの場合は1回、次にXmlSerializerの場合は1回)。特にドキュメントごとにDOMを作成するためのメモリオーバーヘッドを回避します。

より多くの原子力オプションは、バージョン属性を解析し、正しい子タイプをインスタンス化するためのカスタムロジックを持つカスタムクラスのセットにIXmlSerializableを実装します。 List<Car>プロパティを持つCarCollectionクラスです。Carは、子孫としてCarV1およびCarV2を持つ抽象クラスです。これはあなたが得ることができるほど効率的です(クラス階層設計に対する非常に細かい制御を提供します)が、xsd.exeを使用してクラスを生成する可能性を排除します。

関連する問題