0

構造が同一の 2 つの XML ドキュメントがあります。A の要素値が B と異なる場合は、B (または B のコピー) にコピーする必要があります。

明確化のための更新: A の要素値は、文字列 "No Change" か、B で更新する必要がある値を示す何かになります。そのため、ドキュメント全体をコピーすることはできません。要素に「変更なし」がある場合、B の同じ要素に既に存在する値には触れません。「変更なし」以外のものがあれば、その値は B にコピーされます。つまり、B のA に更新された値がない限り、値は残ります。

ソリューションは、xmlDocument または XDocument のいずれかを使用できます。それが機能する限り、私は特にこだわりません。私はフレームワーク 4.0を使用しているので、XDocument がよりモダンなアプローチだと思います。

したがって、ドキュメント A のすべてのノード/要素をトラバースし、B で同じものをクエリして値を比較し、異なる場合は、A 要素の値が B の同じ要素にコピーされる (またはコピーBの)。

私はC#で XML ドキュメントをクエリするまったくの初心者なので、時間を節約するためにここで質問したいと思いました。

ありがとう、

バリー

4

3 に答える 3

0

LINQ to XML (別名XDocumentXElement、およびその他の関連クラス) を使用すると、これは実際には非常に簡単です。以下のコードでは、xmlAxmlBが XDocument の 2 つのインスタンスであり、それぞれ xml ドキュメント A と xml ドキュメント B からデータが読み込まれると想定しています。

string dataA = xmlA.Element("ROOT_ELEMENT").Element("Element1").Value;
if(!dataA.equals("No Change"))
    xmlB.Element("ROOT_ELEMENT").Element("Element1").Value = dataA;

これにより、ルート要素の名前の下にある Element1 という名前の要素の値に「変更なし」の値がないかどうかがチェックされます。true の場合、ドキュメント B の一致する要素の値が更新されます。

編集: 追加の例を追加して、ドキュメント全体をトラバースし、すべての要素に対してこれを行うには:

XElement rootElementA = xmlA.Element("ROOT_ELEMENT");
XElement rootElementB = xmlB.Element("ROOT_ELEMENT");
foreach(XElement element in rootElementA.Elements())
{
    if(!element.Value.Equals("No Change"))
    {    
        XElement e = 
               (from el in rootElementB.Elements() 
               where element.Name == el.Name 
               select el).FirstOrDefault();
         e.Value = element.Value;
     }
 }

いくつかのことを覚えておいてください。上記の例では、ルート要素とその 1 レベル下のすべての要素の 2 つのレベルの要素しかないと仮定しています。XML がさらに深くなる場合はHasElements、ループ内で見つかった個々の要素に対してプロパティを使用する必要があります (つまりif(element.HasElements)、追加のネストされたループを作成して、要素の追加レベルにどんどん深く入り込みます。

于 2013-08-29T17:34:43.073 に答える
0

JNYRanger の提案に基づいて、私は昨夜これを思いつきました:

TraverseNodes(xmlSbcCoreData.ChildNodes);

私のXmlDocumentオブジェクトを渡します...

    private void TraverseNodes(XmlNodeList nodes) {

        Boolean haveValue = false;

        foreach (XmlNode node in nodes) {
            // Do something with the node.

            if (!node.Name.Equals("#text")) {
                nodeName = node.Name;
                capturedNode = node;
                haveValue = false;
            } else {
                nodeValue = node.Value;
                haveValue = true;
            }

            if (haveValue) {
                Debug.WriteLine("-----------------------------------------------------");
                Debug.WriteLine("GetRecursiveList - capturedNode: " + capturedNode.Name);
                Debug.WriteLine("GetRecursiveList capturedNode Parent: " + capturedNode.ParentNode.Name);
                Debug.WriteLine("GetRecursiveList NAME|VALUE: " + nodeName + " | " + nodeValue);

                string path = getNodePath(capturedNode);
                Debug.WriteLine("GetRecursiveList capturedNode PATH: " + path);

                //THIS IS HOW YOU GET THE NODE IN THE OTHER XML
                XElement element = xmlNbidData.XPathSelectElement(path);
                //AND THEN SET ITS VALUE !!!
                element.Value = nodeValue;
            }

            TraverseNodes(node.ChildNodes);
        }

    }

これはランタイム (サンプル) です。


GetRecursiveList - captureNode: hraPlan GetRecursiveList CaptureNode 親:overallDeductible GetRecursiveList NAME|VALUE: hraPlan | はい

GetRecursiveList CaptureNode パス: createSbc/createSbcRequest/sbc/coreData/SBCDataContent/importantQuestions/overallDeductible/hraPlan

GetRecursiveList -capturedNode: deductableCrossApply GetRecursiveList CaptureNode 親:overallDeductible GetRecursiveList NAME|VALUE: deductableCrossApply | いいえ

GetRecursiveList CaptureNode パス: createSbc/createSbcRequest/sbc/coreData/SBCDataContent/importantQuestions/overallDeductible/deductableCrossApply

GetRecursiveList - CaptureNode: yearType GetRecursiveList CaptureNode 親:overallDeductible GetRecursiveList NAME|VALUE: yearType | カレンダー

GetRecursiveList CaptureNode パス: createSbc/createSbcRequest/sbc/coreData/SBCDataContent/importantQuestions/overallDeductible/yearType

GetRecursiveList - captureNode: 個別の GetRecursiveList CaptureNode 親: inNetwork GetRecursiveList NAME|VALUE: 個別 | 0

GetRecursiveList CaptureNode パス: createSbc/createSbcRequest/sbc/coreData/SBCDataContent/importantQuestions/overallDeductible/inNetwork/individual

于 2013-08-30T13:56:47.057 に答える