1

これが取引です。多数のレコードを含む XML ドキュメントがあります。このようなもの:

print("<?xml version="1.0" encoding="utf-8" ?>
      <Orders>
       <Order>
         <Phone>1254</Phone>
         <City>City1</City>
      <State>State</State>
      </Order>
      <Order>
         <Phone>98764321</Phone>
         <City>City2</City>
        <State>State2</State>
      </Order>  
     </Orders>");

XSD スキーマ ファイルもあります。このファイルからデータを抽出し、これらのレコードをデータベース テーブルに挿入したいと考えています。まず、各注文レコードを検証したいと思います。たとえば、ファイルに 5 つの注文があり、そのうちの 2 つが検証に失敗した場合、検証に合格した 3 つをデータベースに挿入し、残りの 2 つを残します。1 つの xml ファイルに何千ものレコードが存在する可能性があります。ここで最善のアプローチは何でしょうか。失敗したレコードを破棄し、検証に合格したレコードのみを使用する必要があるため、検証はどのように行われますか。現時点では、XmlReaderSettingsを使用して XML ドキュメント レコードを検証しています。DB に挿入する前に、これらのレコードを別の XML ファイル、データセット、またはカスタム オブジェクトに抽出する必要があります。私は.Net 3.5を使用しています。コードやリンクは大歓迎です。

4

5 に答える 5

1

データがオブジェクトモデルにかなりきれいにマッピングされている場合は、xsd.exeを使用して.xsdからいくつかのクラスを生成し、選択したDALにクラスを処理してみてください。問題は、ボリュームが大きい場合(数千のレコードについて言及している場合)、多くのラウンドトリップが発生する可能性が高いことです。

もう1つのオプションは、データを「そのまま」データベースに渡し、SQL / XMLを使用してTSQLでデータを処理することです。おそらくxmlタイプのパラメーター(SQL Server 2005など)を受け入れるストアドプロシージャとしてです。

于 2008-10-22T14:08:44.957 に答える
1

XmlReader を使用する必要があるという考えには同意しますが、少し違うことを試してみようと思いました。

基本的に、最初に XDocument 全体を検証し、次にエラーがある場合は注文を列挙し、必要に応じてビンに入れます。きれいではありませんが、いくつかのアイデアが得られるかもしれません。

        XDocument doc = XDocument.Load("sample.xml");
        XmlSchemaSet schemas = new XmlSchemaSet();
        schemas.Add("", "sample.xsd");

        bool errors = false;
        doc.Validate(schemas, (sender, e) =>
        {
            errors = true;
        });

        List<XElement> good = new List<XElement>();
        List<XElement> bad = new List<XElement>();
        var orders = doc.Descendants("Order");
        if (errors)
        {
            foreach (var order in orders)
            {
                errors = false;
                order.Validate(order.GetSchemaInfo().SchemaElement, schemas, (sender, e) =>
                {
                    errors = true;
                });

                if (errors)
                    bad.Add(order);
                else
                    good.Add(order);
            }
        }
        else
        {
            good = orders.ToList();
        }

ラムダ式の代わりに、一般的な関数を使用することもできますが、私はこれをまとめただけです。また、順序要素をリストに押し込む代わりに、2 つの XDocument を作成することもできます。ここには他にもたくさんの問題があると確信していますが、これが何かのきっかけになるかもしれません。

于 2009-05-22T18:43:41.100 に答える
0

いくつかのオプションがあります。

  1. XmlDataDocumentまたはXmlDocument。このアプローチの欠点は、データがメモリにキャッシュされることです。これは、データが大量にある場合には良くありません。一方、DataSet を使用すると、優れたメモリ内クエリ機能を利用できます。XmlDocument では、XPath クエリを使用してデータを処理する必要がありますが、XmlDataDocument では、DataSet 機能に似たエクスペリエンスが得られます。

  2. XmlReader . データがキャッシュされないため、これは優れた迅速なアプローチです。ストリームとして少しずつ読みます。ある要素から次の要素に移動し、アプリケーションでその要素に関する情報を照会して、その要素をどうするかを決定します。これは、現在のツリー レベルをアプリケーションのメモリ内に維持することを意味しますが、あなたのような単純な XML ファイル構造では、これは非常に単純なはずです。

あなたの場合、オプション2をお勧めします。メモリ使用量の点で適切にスケーリングし、ファイルを処理するための最も単純な実装を提供する必要があります。

于 2008-10-22T15:17:51.713 に答える
0

検証とは、各ノードを検証することを意味します。少なくとも 1 つのエラーがあるノードは、新しい xml ドキュメントに挿入する必要があります。基本的に、最後に 2 つの xml ドキュメントが必要です。1 つは成功したノードを含み、もう 1 つは失敗したノードを含みます。それを達成する方法はありますか?私はLINQを使用しています。

于 2008-10-23T07:16:52.103 に答える
0

その多くは、シナリオでの「検証」の意味によって異なります。.xsd を使用しているので、データが構文的に正しいことを既に検証していると思います。では、検証とはおそらく、注文が有効かどうかを判断するために他のサービスまたは手順を呼び出すことを意味するのでしょうか?

Sql Server Integration Services を参照してください。SSIS の XML タスクを使用すると、XPath クエリ、マージなど、そのドキュメントで行う必要のあるあらゆることを実行できます。また、スキーマ ファイルを使用したすべての事前検証にもそれを使用できます。

そのデータをストアド プロシージャに渡すという Marc のオプションは、このシナリオでも機能する可能性がありますが、SSIS (または、DTS でさえも、XML に関連する多くのことを放棄してオプションとして適切なものにすることはできません) を使用すると、視覚的にこのすべての作業を調整します。さらに、これらの処理がアウト プロセスで実行されやすくなるため、よりスケーラブルなソリューションになるはずです。

于 2008-10-22T15:06:38.477 に答える