Search code examples
xmlunitxmlunit-2

XMLUnit Comparing and Storing Specific Values Related to a Found Difference


I am trying to compare two xml files and if a difference is found between two specific items I want to store a key value that also belongs to that item. For example lets say I have the following two XML files:

File 1:

  <associate>
    <vendorCodes>TEST</vendorCodes>
    <vendorCodes>TEST</vendorCodes>
    <vendorCodes>TEST</vendorCodes>
    <associateId>12345</associateId>
    <regionCode>A</regionCode>
    <stateCode>B</stateCode>
    <agentCode>C</agentCode>
    <territoryCode>D</territoryCode>
    <legalName>
        <firstName>Zach </firstName>
        <middleName></middleName>
        <lastName>Benchley</lastName>
        <suffix>     </suffix>
    </legalName>
    <preferredName>
        <firstName>Zach</firstName>
        <middleName> </middleName>
        <lastName>Benchley</lastName>
        <suffix>     </suffix>
    </preferredName>
 </associate>

File 2:

  <associate>
    <vendorCodes>NOTATEST</vendorCodes>
    <vendorCodes>TEST</vendorCodes>
    <vendorCodes>TEST</vendorCodes>
    <associateId>12345</associateId>
    <regionCode>A</regionCode>
    <stateCode>B</stateCode>
    <agentCode>C</agentCode>
    <territoryCode>D</territoryCode>
    <legalName>
        <firstName>Zach </firstName>
        <middleName></middleName>
        <lastName>Benchley</lastName>
        <suffix>     </suffix>
    </legalName>
    <preferredName>
        <firstName>Zach</firstName>
        <middleName> </middleName>
        <lastName>Benchley</lastName>
        <suffix>     </suffix>
    </preferredName>
 </associate>

So in the above example the difference would be thrown because the first vendorCode does not match. So what I want to do is obtain the current new value of vendorCode which would be: NotATest. I am able to do this just fine. However, I also want to store the associateID of the associate that has had a changed. Is there a way to grab the associateID 12345 along with the new value? I see there is a ParentXPath, but is there a way to actually grab that associateID even though that is not the actual difference on that node.

We have files with multiple associates so I want to be able to map differences found to the necessary associateId.

Currently I am able to compare docs that are sent out of order and compare based on associate ID. I just need to be able to grab that value. Here is my code I currently have:

    ElementSelector nodeMatch = ElementSelectors.conditionalBuilder().whenElementIsNamed("associate").thenUse(new AssociateNodeMatcher()).elseUse(ElementSelectors.byName).build();
    Diff myDiff = DiffBuilder.compare(doc1).withTest(doc2).checkForSimilar().ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(nodeMatch)).build();

Then here is my AssociateNodeMatcher:

    public boolean canBeCompared(Element control, Element test) {
    String controlAssociateId = control.getElementsByTagName("associateId").item(0).getTextContent();
    String testAssociateId = test.getElementsByTagName("associateId").item(0).getTextContent();  
    if(controlAssociateId.compareTo(testAssociateId)==0){
        return true;
    }
    return false;
}

}

Any help would be great.


Solution

  • If the difference could be anywhere then you will be forced to doing it with code. I think you could either use XPath or DOM for that. For XPath you'd cut the XPath of your difference back until it selects the proper associate, slap on an associateId and use Java's XPath engine on either the control or test document (the ids should be the same given your node matcher). XMLUnit's XPath API may simplify this.

    The approach using DOM is similar, you'd walk up from the Comparisons target Node until you reach one that's an element named associate.