xml-unit Правильный элемент квалификатора

Этот вопрос следует за моими ограничениями на вопрос модуля xml. Я задаюсь вопросом о лучшем элементе квалификатора.

Теперь я создал два примера XML. К сожалению, я не должен публиковать настоящие. Прилагаемые не имеют никакого смысла, но они достаточно хороши, чтобы показать мою проблему.

В этом случае я хочу, чтобы две машины были найдены одинаковыми, если узел "metainfo" одинаков в обоих случаях. После короткого взгляда на результаты, я думаю, что первая машина в автомастерской сравнивается с первой машиной в смешанной автомастерской. Я думал, что RecursiveElementNameAndTextQualifier должен идентифицировать правильный.

Позже (опять нет смысла, просто пример) появятся клиенты, которые выглядят так:

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

и должен быть идентичен, если идентификатор идентичен.

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();
    }
}

}

Спасибо за помощь

1 ответ

RecursiveElementNameAndTextQualifier является одним из самых цитируемых ElementQualifierвокруг, но это почти никогда не то, что вам нужно. Он сопоставляет два элемента, если их имена совпадают, а имена всех их дочерних элементов (в правильном порядке) совпадают, а вложенный текст всех дочерних элементов (в правильном порядке) совпадает. Это не будет ограничено metainfo ребенок, но используйте вложенные тексты всех детей.

ElementQualifier вызывается для дочерних элементов данного узла, и вам нужно, чтобы он выбрал "правильный" выбор достаточно близко к корню документа. В вашем случае при сравнении car элементы. Для тех, кто вам нужен ElementQualifier который принимает два элемента как сопоставимые, если их metainfo/keynumber вложенные текстовые совпадения ребенка.

Нет встроенного ElementQualifer это было бы достаточно избирательно, вы должны написать это сами. Что еще хуже, что этот обычай ElementQualifier не будет работать ни для одного из других элементов (нет metainf/keynumber ребенок для них), но все равно вы должны использовать один ElementQualifier для всего документа. Это означает, что ваша пользовательская реализация станет еще более сложной.

В XMLUnit 2.x есть другое решение, так как вы можете составить ElementSelectorс (примерно эквивалентно ElementQualifier в 1.х) и есть условный строитель. Что-то вроде

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

вероятно, будет работать.

Другие вопросы по тегам