这个问题是关注我的问题limitations of 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 :(得分:0)
RecursiveElementNameAndTextQualifier
是引用最多的ElementQualifier
之一,但它几乎不是您需要的那个。如果它们的名称匹配并且所有子项的名称(按正确顺序)匹配并且所有子项的嵌套文本(按正确顺序)匹配,则它匹配两个元素。它不仅限于metainfo
孩子,而是使用所有孩子的嵌套文本。
ElementQualifier
,您需要让它选择足够接近文档根的“正确”选项。在您比较car
元素的情况下。对于那些需要ElementQualifier
的人,如果metainfo/keynumber
子项的嵌套文本匹配,则会接受两个可比较的元素。
没有内置的ElementQualifer
足够有选择性,你必须自己写。更糟糕的是,这个自定义ElementQualifier
不适用于任何其他元素(它们没有metainf/keynumber
子元素),但仍然必须使用单个ElementQualifier
作为整体文献。这意味着您的自定义实现将变得更加复杂。
在XMLUnit 2.x中有一个不同的解决方案,因为你可以编写ElementSelector
s(大约相当于1.x中的ElementQualifier
)并且有一个条件生成器。像
ElementSelectors.conditionalBuilder()
.whenElementIsNamed("car").thenUse(ElementSelectors.byXPath("./metainfo/keynumber", ElementSelectors.byNameAndText))
.elseUse(ElementSelectors.byName)
.build();
可能会奏效。