XMLUnit - Issue comparing to XMLs that are not in same order

这一生的挚爱 提交于 2019-12-31 06:56:07

问题


I am using XMLUnit2 to compare 2 XMLs which don't have elements in the same order. I am seeing the below error -

Differences = Expected child 'billingCode' but was 'null' - comparing at /translateServiceRequestResponse[1]/translateServiceRequestReturn[1]/legacyCode[2]/billingCode[1] to NULL

Code

Diff myDiff = DiffBuilder.compare(controlResponse).ignoreWhitespace().ignoreComments().withTest(testResponse).withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)).checkForSimilar().build();
System.out.println("Differences = " + myDiff.toString());

Control File

<translateServiceRequestResponse>
<translateServiceRequestReturn>
    <legacyCode>
        <amount>0</amount>
        <billingCode>VS128</billingCode>
        <description>HD Rec</description>
        <priceName>EquipChoice X1 HD TP</priceName>
        <pricingElementName>X1 HD Receiver</pricingElementName>
        <codeAmount>0</codeAmount>
        <lobSubType>0</lobSubType>
        <addressable>1</addressable>
        <nonStandard>false</nonStandard>
    </legacyCode>
    <legacyCode>
        <amount>0</amount>
        <billingCode>VF123</billingCode>
        <description>HD Rec</description>
        <packageCode>VE286</packageCode>
        <priceName>EquipChoice X1 HD TP</priceName>
        <pricingElementName>X1 HD Receiver</pricingElementName>
        <codeAmount>0</codeAmount>
        <lobSubType>0</lobSubType>
        <addressable>1</addressable>
        <nonStandard>false</nonStandard>
    </legacyCode>
    <legacyCode>
        <amount>0</amount>
        <billingCode>VF170</billingCode>
        <description>HD Rec</description>
        <packageCode>VE286</packageCode>
        <priceName>EquipChoice X1 HD TP</priceName>
        <pricingElementName>X1 HD Receiver</pricingElementName>
        <codeAmount>2.5</codeAmount>
        <lobSubType>0</lobSubType>
        <addressable>1</addressable>
        <nonStandard>false</nonStandard>
    </legacyCode>
</translateServiceRequestReturn>

Test File

<translateServiceRequestResponse>
<translateServiceRequestReturn>
    <legacyCode>
        <amount>0</amount>
        <billingCode>VS128</billingCode>
        <description>HD Rec</description>
        <priceName>EquipChoice X1 HD TP</priceName>
        <pricingElementName>X1 HD Receiver</pricingElementName>
        <codeAmount>0</codeAmount>
        <lobSubType>0</lobSubType>
        <addressable>1</addressable>
        <nonStandard>false</nonStandard>
    </legacyCode>
    <legacyCode>
        <amount>0</amount>
        <billingCode>VF170</billingCode>
        <description>HD Rec</description>
        <packageCode>VE286</packageCode>
        <priceName>EquipChoice X1 HD TP</priceName>
        <pricingElementName>X1 HD Receiver</pricingElementName>
        <codeAmount>2.5</codeAmount>
        <lobSubType>0</lobSubType>
        <addressable>1</addressable>
        <nonStandard>false</nonStandard>
    </legacyCode>
    <legacyCode>
        <amount>0</amount>
        <billingCode>VF123</billingCode>
        <description>HD Rec</description>
        <packageCode>VE286</packageCode>
        <priceName>EquipChoice X1 HD TP</priceName>
        <pricingElementName>X1 HD Receiver</pricingElementName>
        <codeAmount>0</codeAmount>
        <lobSubType>0</lobSubType>
        <addressable>1</addressable>
        <nonStandard>false</nonStandard>
    </legacyCode>
</translateServiceRequestReturn>


回答1:


XMLUnit uses the ElementSelector in order to determine which elements of two sets of siblings in the control and test documents to match with each other. It will start matching from the root of the documents and you must ensure it picks the correct branches at each level. Once a decision has been made, XMLUnit won't back-track.

When picking an ElementSelector you must always ensure it helps XMLUnit to take the correct branch as close to the root of the document as the logical structure of your document requires. The elements you say are not in the same order are the legacyCode elements, so you must help XMLUnit to make the correct selection among them. byNameAndText won't help here. There is no nested text in byNameAndText at all, so they are all the same and XMLUnit matches the elements in document order.

This is exactly the same problem as the one about trs in https://github.com/xmlunit/user-guide/wiki/SelectingNodes

To me looks as if your legacyCode would be identified by the text nested into the billingCode element. If so you could use an ElementSelector like

ElementSelectors.conditionalBuilder()
    .whenElementIsNamed("legacyCode").thenUse(ElementSelectors.byXPath("./billingCode", ElementSelectors.byNameAndText))
    .elseUse(ElementSelectors.byName)
    .build();

You may need to adapt this so it works for parts of the of the document you haven't shown or if byNameAndText really is required rather than byName for some other parts of the tree.



来源:https://stackoverflow.com/questions/44064675/xmlunit-issue-comparing-to-xmls-that-are-not-in-same-order

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!