2016-10-26 48 views
0

這個問題跟在我的問題limitations of xml unit。 我想知道最好的元素限定符。xml-unit正確的元素限定符

現在我創建了兩個示例XML。不幸的是,我不能發佈真正的。附加的沒有任何意義,但它們足以證明我的問題。

在這種情況下,如果在兩種情況下「metainfo」節點相同,我希望找到兩輛相似的車。我認爲,在對產量進行簡短的觀察之後,我們將這家汽車購物中心的第一輛汽車與混合購物車中的第一輛汽車進行了比較。 我認爲,RecursiveElementNameAndTextQualifier應該識別正確的。

後來(再沒有任何意義,只是一個例子)會有一些客戶看起來像:

<customer> 
<age></age> 
<gender></gender> 
<db_info> 
    <id></id> 
    <…></…> 
</customer> 

,應該相同,如果ID是相同的。

carshop.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<delivery> 
<cars> 
    <car> 
     <number>g:ki:1675</number> 
     <manufactor>npqhtgmmfh</manufactor> 
     <age>2</age> 
     <localcar_id>6213</localcar_id> 
     <metainfo> 
      <keynumber>424</keynumber> 
      <colour>1</colour> 
     </metainfo> 
    </car> 
    <car> 
     <number>b:ra:5287</number> 
     <manufactor>tjmeugqcar</manufactor> 
     <localcar_id>625</localcar_id> 
     <metainfo> 
      <keynumber>3238</keynumber> 
      <colour>3</colour> 
     </metainfo> 
    </car> 
    <car> 
     <number>v:eu:5387</number> 
     <localcar_id>4910</localcar_id> 
     <metainfo> 
      <keynumber>618</keynumber> 
      <colour>6</colour> 
     </metainfo> 
    </car> 
    <car> 
     <number>f:fu:8242</number> 
     <manufactor>ckpoaskabi</manufactor> 
     <age>9</age> 
     <localcar_id>8044</localcar_id> 
     <metainfo> 
      <keynumber>9865</keynumber> 
      <colour>6</colour> 
     </metainfo> 
    </car> 
</cars> 
</delivery> 

mixedcarshop

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<delivery> 
<cars> 
    <car> 
     <number>f:fu:8242</number> 
     <manufactor>ckpoaskabi</manufactor> 
     <age>9</age> 
     <localcar_id>8044</localcar_id> 
     <metainfo> 
      <keynumber>3238</keynumber> 
      <colour>3</colour> 
     </metainfo> 
    </car> 
    <car> 
     <number>b:ra:5287</number> 
     <manufactor>tjmeugqcar</manufactor> 
     <localcar_id>625</localcar_id> 
     <metainfo> 
      <keynumber>9865</keynumber> 
      <colour>6</colour> 
     </metainfo> 
    </car> 
    <car> 
     <number>v:eu:5387</number> 
     <localcar_id>4910</localcar_id> 
     <metainfo> 
      <keynumber>424</keynumber> 
      <colour>1</colour> 
     </metainfo> 
    </car> 
    <car> 
     <number>g:ki:1675</number> 
     <manufactor>npqhtgmmfh</manufactor> 
     <age>2</age> 
     <localcar_id>6213</localcar_id> 
     <metainfo> 
      <keynumber>618</keynumber> 
      <colour>6</colour> 
     </metainfo> 
    </car> 
</cars> 
</delivery> 

Java代碼:

import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileReader; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 
import org.custommonkey.xmlunit.DetailedDiff; 
import org.custommonkey.xmlunit.Diff; 
import org.custommonkey.xmlunit.Difference; 
import org.custommonkey.xmlunit.XMLUnit; 
import org.custommonkey.xmlunit.examples.RecursiveElementNameAndTextQualifier; 



public class Arbeiter { 

private File quelle, vergleich; 

public Arbeiter(File quelle, File vergleich) { 
    this.quelle=quelle; 
    this.vergleich=vergleich; 
} 

public void vergleichen() 
{ 
    long tbevore = System.currentTimeMillis(); 
    XMLUnit.setIgnoreAttributeOrder(Boolean.TRUE); 
    XMLUnit.setIgnoreWhitespace(Boolean.TRUE); 
    String f1 = lesen(quelle); 
    String f2 = lesen(vergleich); 

    try { 
     Diff diff = new Diff(f1, f2); 
     diff.overrideElementQualifier(new RecursiveElementNameAndTextQualifier()); 
     List<String>liste = new ArrayList<String>(); 
     liste.add("number"); 
     liste.add("manufactor"); 
     liste.add("age"); 
     liste.add("localcar_id"); 
     //diff.overrideDifferenceListener(new IgnoreNamedElementsDifferenceListener(findSVSW_ID(quelle))); 
     diff.overrideDifferenceListener(new IgnoreNamedElementsDifferenceListener(liste)); 
     DetailedDiff dd = new DetailedDiff(diff); 
     boolean result = dd.similar(); 

     StringBuilder sb = new StringBuilder(); 

     sb.append("Die Dateien "+quelle.getName() +" und "+vergleich.getName()+" wurden miteinander verglichen \n \n"); 
     if (result ==true) 
     { 
      sb.append("Die Dateien sind inhaltsgleich \n"); 
     } 
     else 
     { 
      sb.append("Die Dateien unterscheiden sich \n \n"); 
      List<Difference>list = dd.getAllDifferences(); 
      for (Difference aktuell : list) 
      { 
       if (!aktuell.isRecoverable()) 
       { 
        sb.append("Der Ausdruck "+aktuell.getControlNodeDetail().getValue()+" wurde gesucht \n"); 
        sb.append("Der Ausdruck "+aktuell.getTestNodeDetail().getValue()+" wurde gefunden \n"); 
        sb.append("Xpath: "+aktuell.getTestNodeDetail().getXpathLocation()+"\n \n"); 

       } 
      } 
     } 
     long tafter = System.currentTimeMillis(); 
     String dauer = Long.toString((tafter-tbevore)/1000); 
     sb.append("Die Bearbeitung dauerte " +dauer+" Sekunden \n"); 
     speichern(sb.toString()); 
     System.out.println("Bearbeitung abgeschlossen. Die Ausgabedatei wurde unter " +quelle.getParent()+"/ausgabe.txt abgelegt"); 

    } 
    catch (Exception e) 
    { 
     e.printStackTrace(); 
    } 




} 

private String lesen(File datei) 
{ 
    String result =""; 
    try { 
     BufferedReader leser = new BufferedReader(new FileReader(datei)); 
     StringBuilder sb = new StringBuilder(); 
     String gelesen = leser.readLine(); 
     while (gelesen!=null) 
     { 
      sb.append(gelesen); 
      gelesen=leser.readLine(); 
     } 
     result=sb.toString(); 
     leser.close(); 
    } catch (FileNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    return result; 
} 

private List<String> findSVSW_ID(File datei) 
{ 
    List<String>liste = new ArrayList<String>(); 
    liste.add("AUFTRAGSCHLUESSEL"); 
    liste.add("LIEFERUNGSCHLUESSEL"); 
    try { 
     BufferedReader leser = new BufferedReader(new FileReader(datei)); 
     String gelesen = leser.readLine(); 
     while (gelesen!=null) 
     { 
      if (gelesen.contains("SVSW_ID")) 
      { 
       String [] teile = gelesen.split(">"); 
       String temp = teile[0].replaceAll("<", ""); 
       if (!liste.contains(temp)) 
       { 
        String t2=temp.replaceAll(" ", ""); 
        liste.add(t2); 
       } 

      } 
      gelesen=leser.readLine(); 
     } 


    } catch (FileNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 


    return liste; 
} 

private void speichern(String text) 
{ 
    File datei = new File(quelle.getParent()+"/ausgabe.txt"); 
    try { 
     BufferedWriter schreiber = new BufferedWriter(new FileWriter(datei)); 
     schreiber.write(text); 
     schreiber.flush(); 
     schreiber.close(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

} 

感謝您的幫助

回答

0

RecursiveElementNameAndTextQualifier是被引用最多的一個ElementQualifier周圍,但它幾乎從來不是你需要的那個。它匹配兩個元素,如果他們的名字匹配並且他們所有孩子的名字(以正確順序)匹配並且所有孩子的嵌套文本(以正確順序)匹配。它不會被限制在metainfo孩子,但使用嵌套文本所有孩子。

ElementQualifier在給定節點的子元素上被調用,您需要讓它選擇足夠接近文檔根的「正確」選項。在你的情況下,比較car元素。對於那些你需要的ElementQualifier,如果它們的metainfo/keynumber孩子的嵌套文本匹配,則接受兩個可比較元素。

沒有內置的ElementQualifer這將是足夠選擇性的,你必須自己寫。更糟糕的是,這個自定義ElementQualifier將不適用於任何其他元素(他們沒有metainf/keynumber孩子),但仍然必須使用單個ElementQualifier作爲整個文檔。這意味着您的自定義實現將變得更加複雜。

在XMLUnit 2.x中有一個不同的解決方案,因爲您可以編寫ElementSelector(大致相當於1.x中的ElementQualifier),並且有一個條件構建器。類似於

ElementSelectors.conditionalBuilder() 
    .whenElementIsNamed("car").thenUse(ElementSelectors.byXPath("./metainfo/keynumber", ElementSelectors.byNameAndText)) 
    .elseUse(ElementSelectors.byName) 
    .build(); 

可能會工作。