4

XML データ ドキュメントへの変更のリストをインポートおよびエクスポートする方法を探しています (不規則な構造です。DataSet に自然に適合しません)。

通常の構造であれば、DataTable を使用し、どのレコードが編集されたかを評価して、変更をコミットまたはキャンセルし、必要な変更のパケットを送信することもできます。

XML データでこれを行うにはどうすればよいですか?

適切な答えが得られない場合、非効率的なストレージとナビゲーションの問題にもかかわらず、スキーム [XPath, Value] で DataTable を使用するのが最善の策だと思います。

ドキュメントに変更を加えて (XPath、LINQ、データ バインド コントロールなどを使用して)、変更を記憶し、TCP 経由で変更のみを送信することを期待しています。

次に、別の変更リストを受け取り、それを XML ドキュメントに適用したいと考えています。サイズと送信される変更を知り、評価する必要があるため、ドキュメント全体を送信したくありません。

(明確にするために:私のプログラムはドキュメントの変更を送受信する必要があります。パイプのもう一方の端は.netに基づいておらず、この質問の一部ではありません。)

4

7 に答える 7

1

この変更に対応する必要がありますか、それとも単に保存する必要がありますか。更新されたバージョンを保存するだけの場合は、バイナリ差分アルゴリズムを使用して2つのxmlファイル間の差分を渡すことができます。そして、違いのある更新された保存バージョンに。このための適切なアルゴリズムはbifdiffです 。C#バージョンはここにあります。

もう1つのアプローチは、MSのこのXmlDiffクラスを使用することです。

于 2012-09-05T21:10:42.333 に答える
1
  1. 変更のみを送信するにはどうすればよいでしょうか。
  2. 多くの変更を期待していますか、それとも毎回わずかな変更しか期待していませんか?
  3. どのような変更を検討する必要がありますか?
  4. プロセスの境界を越えて同じドキュメントのコピーを維持しようとしていますか?
  5. 競合する変更をどのように解決しますか?
  6. 変更が反映されるまで xml ドキュメントをロックしますか?
  7. 両方のコピーが独立しているか、または一方がマスター コピーか?

NodeInserted、NodeDeleted、NodeChanged などの XmlDocument イベントを使用した場合、そのような変更のリストを作成し、別のコピーでそれらを実行できます。変更の合計量がドキュメント自体よりも長い場合は、代わりにドキュメントを送信できます。xml データの圧縮も役立ちます。

それ以外には、他の簡単なアプローチは見当たりません。

于 2012-09-07T10:31:57.550 に答える
0

ここでの問題は、XMLは単なるデータの表現形式であり、必ずしもデータ自体ではないということです。これはあなたが使用しているある種のXMLエディターですか、それともXMLは単なるトランスポートですか?

トランスポートとしてのxmlについて話している場合、XML変更の説明の送信について話しているときは、変更自体を生成する時点でそれらの変更の説明を生成する必要があります。変更の説明が生成されない可能性があります。元のデータと同じスキーマにあります。

さらに、データセットがこれを実行できる理由は、データセットの各行に既知の一意のキーがあるためです。そのため、セット全体ではなく、行の変更を送り返すことができます。XMLはそのようには機能せず、各行に一意のキーがありません。XPathは変更ロケーターとして使用できますが、十分な編集を加えてドキュメント全体を送信するよりも非効率的である可能性があります。

標準のパッチ適用アルゴリズムのいずれかを使用するように、XMLをテキストとして単純に扱ってみませんか?(GitまたはHgのソースを見てください)

于 2012-09-06T22:46:16.657 に答える
0

不規則な構造のXMLデータを取得する場合。DataSetを自然に適合させるのではなく、オブジェクトモデルがデータを簡単に操作できるようにする必要があります。XMLスキーマ定義ツール(Xsd.exe)を/ classesオプションとともに使用して、XMLファイルからC#またはVB.Netクラスを生成できます。

XSD.exeは次の場所にあります:

C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\xsd.exe
C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\xsd.exe

VisualStudioコマンドラインからxsd.exeを実行します。 -スタート-すべてのプログラム
-VisualStudio- ツール - コマンドライン



これは、すべてのXSDコマンドラインパラメーターを表示するコマンドです。

xsd /?

不規則なXMLファイル(XmlResponseObject.xml)をクラスに変換するには:

xsd c:\Temp\XmlResponseObject.xml /classes /language:CS /out:c:\Temp\

これにより、XMLを表すクラスを含むcsharpファイルが生成されます。名前空間によって明確にされる単一ファイル内の重複クラスに注意して、それを別々のクラスファイルに再生成することをお勧めしますいずれにせよ、クラスはすべてのxml属性で見栄えが良くなることはありませんが、良い部分はXMLを介してそれらにバインドできることです。これは、REST Webサービスを介してXMLを取得する例です。xmlResponseObjectは、XMLに適合するクラスのObjectModelです。

public interface IYourWebService
{
    XmlResponseObject GetData(int dataId);
}

public class YourWebService : IYourWebService
{
    public XmlResponseObject GetData(int dataId)      
    {
        XmlResponseObject xmlResponseObject = null;
        var url = "http://SomeSite.com/Service/GetData/" + dataId;
        try
        {
         var request = WebRequest.Create(url) as HttpWebRequest;
         if (request != null)
         {
            request.AllowAutoRedirect = true;
            request.KeepAlive = true;
            request.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 1.1.4322; InfoPath.2; .NET4.0C; .NET4.0E)";
            request.Credentials = CredentialCache.DefaultNetworkCredentials;
            request.CookieContainer = new CookieContainer();
            var response = request.GetResponse() as HttpWebResponse;
            if (request.HaveResponse && response != null)
            {
                var streamReader = new StreamReader(response.GetResponseStream());
                var xmlSerializer = new XmlSerializer(typeof(XmlResponseObject));
                xmlResponseObject = (XmlResponseObject)xmlSerializer.Deserialize(streamReader);
            }
         }
        }
        catch (Exception ex)
        {
        string debugInfo = "\nURL: " + url;
        Console.Write(ex.Message + " " + debugInfo + " " + ex.StackTrace);
        }
    return xmlResponseObject;
    }
}

ドキュメントの変更のみを送受信したい場合は、IsDirtyフラグを使用してクラスを変更できます。作業するクラスができたら、diffを簡単に検出できると確信しています。

于 2012-09-02T02:34:21.460 に答える
0

これまで何度も無料またはオープンソースの XML diff ツールを見つけようとしましたが、本当に目的にかなうものは見つかりませんでした。基本的に、あなたは木の差分を見ています。これはそれ自体が完全な分野です。XML を使用しているという事実は、別の形式のツリーにすぎないため、これに従属していると思います。ノードを指定するものを定義する必要があります。

Tree Edit Distanceの分解アルゴリズムは 2 本の木の間の距離を計算しますが、それを変換してすべての変更を与えることができると思います。これが距離測定のベースであるためです。検出後の変更をどのように伝えるかは、完全にあなた次第です。その範囲は、XML から JSON までさまざまです。アルゴリズムの作成者は、数十行で Python バージョンを作成したと述べていることに注意してください。そのため、a 行を削除すると、彼らが役立つ可能性があります。

あなたがこれを成し遂げることができれば、実用的な概念実証を公開する最初の人になることができるようです:)

于 2012-09-06T20:56:38.653 に答える
0

XML データを にロードするにDataSetは、対応するスキーマを提供する必要があります。XML スキーマ (XSD) からの DataSet リレーショナル構造の導出
を参照してください。

また、DataSet/DataTableは XML 文書では機能しません。XMLからデータをインポートしたり、XML にデータをエクスポートしたりできます。

于 2012-09-04T10:54:57.520 に答える
0

どこにも有用な答えが見つかりませんでした。2003年に、MSはXPathDocument2または私が求めているものを実装する何かを作成することについて話していたようです(次のリリースについて話している本はそれについて言及しています)が、実行されていないようです. だからここに私の解決策があります:

XPathDocument/XPathNavigator を使用し、Change/Delete/Insert のイベント ハンドラーを追加します。これらのイベントごとに、レコードを DataTable {XPath | 古い値 | 変更を示す NewValue}。コミットする準備ができたら、テーブルを送信してクリアします。代わりにキャンセルする場合は、テーブル情報を使用して XPathDocument の変更を元に戻します。

これはまだ実装していませんが、役立つようです。

于 2012-09-05T15:43:08.077 に答える