Сравните Xml в тексте модуля Java, игнорируя атрибут в узле

Мне нужно сравнить 2 строки xml.

Действительный

<?xml version="1.0" encoding="utf-8"?>
    <entry xmlns="http://www.w3.org/2005/Atom"
        xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
        xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
        xml:base="http://localhost:49531/ODataV2.svc/ODataV2.svc/">
        <content type="application/xml">
            <m:properties>
                <d:ID>2000</d:ID>
                <d:ReleaseDate>1992-01-01T00:00:00</d:ReleaseDate>
                <d:Rating>4</d:Rating>
                <d:Price>2.5</d:Price>
            </m:properties>
        </content>
    </entry>

Ожидал

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom"
    xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
    xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
    xml:base="http://localhost:55615/ODataV2.svc/ODataV2.svc/">
    <content type="application/xml">
        <m:properties>
            <d:ID>2000</d:ID>
            <d:ReleaseDate>1992-01-01T00:00:00</d:ReleaseDate>
            <d:Rating>4</d:Rating>
            <d:Price>2.5</d:Price>
        </m:properties>
    </content>
</entry>

приведенный ниже код не работает, потому что номер порта в атрибуте xml:base отличается в корневом узле.

XMLAssert.assertXMLEqual(Actual, Expected);

Ожидаемое значение атрибута 'http://localhost:55615/ODataV2.svc/ODataV2.svc/', но был 'http://localhost:49531/ODataV2.svc/ODataV2.svc/'

номер порта в модульном тесте изменяется во время выполнения. Есть ли способ игнорировать конкретный атрибут и сравнить xml.


person Saranya Baskaran    schedule 07.02.2017    source источник
comment
возможный дубликат stackoverflow.com/questions/1241593/ и stackoverflow.com/questions/5249031/   -  person Redlab    schedule 07.02.2017


Ответы (4)


Решение найдено. Я использовал библиотеку custommonkey для сравнения xml. Вместо XMLAssert.assertXMLEqual(Actual, Expected);

Я использовал приведенный ниже код, чтобы определить разницу.

Diff diff=XMLUnit.compareXML(Expected,Actual);
    diff.overrideDifferenceListener(new DifferenceListener() {
       public void skippedComparison(Node arg0, Node arg1) {
       }

       public int differenceFound(Difference difference) {
        if (difference.getControlNodeDetail().getXpathLocation().contains("entry")) {
            return DifferenceListener.RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
        } else {
            return DifferenceListener.RETURN_ACCEPT_DIFFERENCE;
        }
        }
    });
XMLAssert.assertXMLIdentical(diff,true);
person Saranya Baskaran    schedule 24.02.2017

Я знаю, что это не будет самым крутым или причудливым решением, но вы можете «разобрать» оба XML перед их сравнением и удалить или изменить значение этого атрибута на что-то похожее в обоих, поэтому, когда вы позже сравните их, вы уверены, что это не повлияет на результат

person Armando SM    schedule 07.02.2017
comment
В общем, это единственное решение. Способ игнорировать различия состоит в том, чтобы замаскировать их, нормализовав оба значения (обычно с помощью XSLT), чтобы исключить области/узлы, где различия вас не интересуют. - person Michael Kay; 07.02.2017

XMLUnit 2.x имеет концепцию NodeFilters и AttributeFilters, которые являются простыми Predicates.

assertThat(Actual, isIdenticalTo(Expected)
    .withAttributeFilter(a -> !"base".equals(a.getName())))

наверное сработало бы.

person Stefan Bodewig    schedule 08.02.2017

Возможно, вы можете настроить контекст пространства имен:

http://xmunit.sourceforge.net/api/org/custommonkey/xmlunit/XMLUnit.html#getXpathNamespaceContext()

person thopaw    schedule 07.02.2017