2010-12-30 26 views
2

私は以下のような種類のXMLを解析して、XMLの下に示すようなオブジェクトの集合に到達する良い方法を見つけ出しています。あなたのことを思い出してください。セットアップ全体が動的になり、入ってくるXMLのスキーマが変わる可能性があります。結果オブジェクトはではなく、に変更されます!そのため、私は入力xmlを解析するために使用するマッピングXMLを作成しています。linq経由でXMLを解析する

ここには、データxmlの小さな例があります。 <DATASET>を除いて、多くの(20-30)の「テストレコード」と異なるデータタイプが存在します。

<TESTREPORT> 
<DATASET> 
    <TESTRECORD> 
     <ID_SOURCE>Common Value A</ID_SOURCE> 
     <TESTDATA> 
     <TEST_NAME>Record Number</TEST_NAME> 
     <TEST_VALUE>12345</TEST_VALUE> 
     </TESTDATA> 
     <TESTDATA> 
     <TEST_NAME>Software Part Number</TEST_NAME> 
     <TEST_VALUE>111111</TEST_VALUE> 
     </TESTDATA> 
    </TESTRECORD> 
    <TESTRECORD> 
     <ID_SOURCE>Common Value B</ID_SOURCE> 
     <TESTDATA> 
     <TEST_NAME>Record Number</TEST_NAME> 
     <TEST_VALUE>23456</TEST_VALUE> 
     </TESTDATA> 
     <TESTDATA> 
     <TEST_NAME>Unit Checksum</TEST_NAME> 
     <TEST_VALUE>ABCDEF23</TEST_VALUE> 
     </TESTDATA> 
    </TESTRECORD> 
</DATASET> 

は、ここで私が想像していたマッピングXMLの最初のドラフトです。私が現在抱えている問題は、<ID_SOURCE> - 値を "LOOQ to XML"を使用して<TESTDATA>要素を反復処理する際に "スティック"にする方法です。ここで

<segment code="TEST" segmentid="2"> 
<datadetails> 
    <datadetail path="REPORT/DATASET/TESTRECORD"> 
     <datapoint name="Source" path="ID_SOURCE" sticky="??" /> 
     <datapoint name="Data" path="TESTDATA/TEST_NAME" /> 
     <datapoint name="Value" path="TESTDATA/TEST_VALUE" /> 
    </datadetail> 
</datadetails> 

オブジェクト(またはそれらのシリーズ)である私が作成する必要があります。

new Detail { Source = "Common Value A", Data = "Record Number", Value = "12345" }; 
new Detail { Source = "Common Value A", Data = "Software Part Number", Value = "111111" }; 
new Detail { Source = "Common Value B", Data = "Record Number", Value = "23456" }; 
new Detail { Source = "Common Value B", Data = "Unit Checksum", Value = "ABCDEF23" }; 

私はちょうど私のn番目のアプローチを投げたし、入力を探しています。あなたの助けが大変ありがとう!

+0

私は優れたLINQPadを使用してこれをプロトタイプしているので、共有するコードはありません。私は価値のあるものを保存していません。 – austriacus

+0

"入ってくるxmlのスキーマは変更 " - 実行時に*変更できますか?動的にマッピングを調整できるエンジンを構築するための*唯一の*理由となるIMO。あなたがコード*を書くのに十分な時間の変化についていつも気づいているのであれば、@Anthony Pegramの答えはコードがどれくらい単純かを実証しています。とにかくチューリング完全な言語である時間的なアプローチになるいくつかのxmlベースのシステムよりもC#を編集する必要があるのはずっと良いです(もう一度IMO) - メンテナンスがはるかに難しいものを除いて... – AakashM

+0

@AakashM - あなたの意見はよく撮られています。しかし、ベンダーは3週間ごとにソフトウェアのアップデートを出荷しています(!)ので、いつでもXMLのスキーマを変更することができます。おそらく、3週間ごとに小さな変更を加えても新しいコードを再デプロイしなければならないメンテナンスの悪夢となりそうです。さらに、ユーザーがベンダーのソフトウェアを通じてデータを送信する方法のため、xmlスキーマの複数のバージョンをサポートする必要があります。バランスを崩さなければならないことは分かっていますが、これは比較的重要な「機能」です。 – austriacus

答えて

2

あなたは、そのクラスを定義したと仮定すると(これは、単一IEnumerable<Detail>を生産、各TESTRECORD要素に共通のID_SOURCEを抽出し、内側のTESTDATA要素にそれを適用し、基本的にあなたのXMLを超えるSelectManyだこの

var results = from testRecord in xdocument.Descendants("TESTRECORD") 
       let source = testRecord.Element("ID_SOURCE").Value 
       from testData in testRecord.Elements("TESTDATA") 
       select new Detail 
       { 
        Source = source, 
        Data = testData.Element("TEST_NAME").Value, 
        Value = testData.Element("TEST_VALUE").Value 
       }; 

をお試しください)。

+0

アンソニー、それは素晴らしいです!本当にありがとう! これを動的にするために、マッピングXMLに依存するには、どのようにアプローチしますか? – austriacus

+0

@ austriacus、それは本当にダイナミックなダイナミックな方法になります。 XMLフォーマットが本当に予測不可能な場合は、十分な時間をコーディングする必要があります。つまり、コードスニペットは、提供されたXMLに準拠しています。それはDATASETの単一の言及を含んでいないので、FOO、BARなどの中に含まれるTESTRECORD要素も取り出すことに注意してください。 –

+0

それはスーパーダイナミックではありません。スキーマが変更された場合(ベンダーから提供される場合)、そのことが分かります。しかし、私は不必要なコードの変更を避けるために最善を尽くしており、ほとんどの変更はマッピングXMLによって駆動されます。 – austriacus

関連する問題