XMLUnit - 与不同顺序的XML进行比较的问题

时间:2017-05-19 08:05:16

标签: java xmlunit xmlunit-2

我使用XMLUnit2比较2个没有相同顺序元素的XML。我看到以下错误 -

  

差异=预期的孩子'billingCode'但是'null' - 比较    在   / translateServiceRequestResponse [1] / translateServiceRequestReturn [1] / legacyCode [2] / billingCode [1]为NULL

代码

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

控制文件

<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>

测试文件

<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 个答案:

答案 0 :(得分:2)

XMLUnit使用ElementSelector来确定控件和测试文档中两组兄弟节点的哪些元素相互匹配。它将从文档的根开始匹配,您必须确保它在每个级别选择正确的分支。一旦做出决定,XMLUnit将不会回溯。

选择ElementSelector时,您必须始终确保它可以帮助XMLUnit将正确的分支作为文档的根目录接近文档的根目录。您所说的元素的顺序不同是legacyCode元素,因此您必须帮助XMLUnit在它们之间进行正确的选择。 byNameAndText在这里无济于事。 byNameAndText中根本没有嵌套文本,所以它们都是相同的,XMLUnit与文档顺序中的元素匹配。

这与https://github.com/xmlunit/user-guide/wiki/SelectingNodes

中关于tr的问题完全相同

向我看起来好像你的legacyCode将被嵌套在billingCode元素中的文字识别出来。如果是这样,您可以使用ElementSelector之类的

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

您可能需要对此进行调整,以使其适用于您未显示的文档的部分内容,或者是否真的需要byNameAndText而不是byName树的其他部分。< / p>