2017-08-04 12 views
0

2つのXMLファイルを比較し、すべての違いを記録しようとしています。この問題は、ノードが繰り返し始めるときに発生します。2つのXMLDocumentツリーを繰り返しノードと比較する

<root> 
    <a/> 
    <a/> 
    <b/> 
</root> 

と::二つのファイルについて

<root> 
    <a/> 
    <b/> 
</root> 

私のプログラムは、現在どんな違いを記録しません。以下のように(大きくて醜い)メソッドは次のとおりです。

private void searchDocumentTrees (Node nodeA, Node nodeB, ArrayList<String> differences) { 
    if (nodeA.hasChildNodes() && !nodeB.hasChildNodes()) { 
     // record A deeper at this node 
     return; 
    } 
    else if (!nodeA.hasChildNodes() && nodeB.hasChildNodes()) { 
     // record B deeper at this node 
     return; 
    } 

    else if (!nodeA.hasChildNodes() && !nodeB.hasChildNodes()) { 
     return; 
    } 
    NodeList childrenA = nodeA.getChildNodes(); 
    NodeList childrenB = nodeB.getChildNodes(); 

    // indexes of nodes present in both lists of children as 
    // NodeList doesn't allow searching by value 
    ArrayList<Integer> presentInBothIndexA = new ArrayList<>(); 
    ArrayList<Integer> presentInBothIndexB = new ArrayList<>(); 

    // check for nodes present in both trees, record those present only in A 
    for (int indexA = 0; indexA < childrenA.getLength(); indexA++) { 
     boolean isPresentInBoth = false; 
     Node currentA = childrenA.item(indexA); 
     if (currentA.getNodeType() == Node.ELEMENT_NODE) { 

      for (int indexB = 0; indexB < childrenB.getLength(); indexB++) { 
       Node currentB = childrenB.item(indexB); 
       if (currentB.getNodeType() == Node.ELEMENT_NODE) { 
        // if the nodes match, record their indexes and break from inner loop 
        if (currentA.getNodeName().equals(currentB.getNodeName())) { 
         isPresentInBoth = true; 
         presentInBothIndexA.add(indexA); 
         presentInBothIndexB.add(indexB); 
         break; 
        } 
       } 
      } 

      // if the flag has not been changed currentA is not present in childrenB 
      if (!isPresentInBoth) { 
       // record as present only in A 
      } 
     } 
    } 

    // record nodes present only in B 
    for (...){ 
      /* same nested loop - this time the outer is iterating over B 
      and matching nodes indexes are not recorded - record only B - A */ 
    } 

    for (int indexBoth = 0, len = presentInBothIndexA.size(); indexBoth < len; indexBoth++) { 
     Node currentA = childrenA.item(presentInBothIndexA.get(indexBoth)); 
     Node currentB = childrenB.item(presentInBothIndexB.get(indexBoth)); 
     searchDocumentTrees(currentA,currentB,differences); 
    } 



} 

私の最初の概念は両方のファイルで出現のカウンタのisPresentInBothフラグを置き換えることでしたが、これはおそらく、もっと複雑になるため、第3のループをご紹介します。あなたは良いアイデアを持っていますか?

答えて

0

Iは、2つの解決策が見つかりました:(非効率的な)種々の試みの後

溶液1

は例えばに近づきますノードの出現を数え、それらをハッシュテーブルに格納することによって、同じノードのインデックスを格納する構造体が得られることがわかりました。これは当然であった:

ArrayList<Integer> presentInBothIndexA = new ArrayList<>(); ArrayList<Integer> presentInBothIndexB = new ArrayList<>();

だからではなく、ただ彼らは私が仕事にそれらを置く、ハングアップさせる:

for (nodeB in B) { 
    if (!presentInBothIndexB.contains(indexB)) 
     //record difference - we only need to look for the nodes, that were skipped 
     //by the first loop, i.e. not present in file A 

// pseudo-code for simplification 
for(nodeA in fileA) { 
    for(nodeB in fileB) { 
     // check all the aforementioned conditions 
     if(presentInBothIndexB.contains(indexB)) 
      continue; // skip if it was already recorded 
     // else, do all the other stuff - isPresentInBoth = true, and so on 

は今第二のループは、内部ループを必要としません。

このアプローチには、ファイルに入れられた順番でノードを比較するため、その場合の短所があります。

<r> 
    <a/> 
    <a/> 
    <a><b/></a> 
</r> 

と:

<r> 
    <a/> 
    <a/> 
</r> 

それは、ノードの異なる数があることを記録しますが、最初のファイルに深いを検索しないでしょう。これは、2つのノードを同一として記録した後、単にそれ以上見えないという事実によるものです。それは迷惑ですが、私たちはその前提を作ることができたと思います。

SOLUTION 2. だけXMLUnitを使用します。しかし、その後、また、属性と値を比較すると、全体のことはMIがにもたらした、メシエとメシエを取得しますがあります。真剣に。

関連する問題