Menu

XMLUnit-2 is failing with `withNodeMatcher` API for random order of List<Map>

Help
2021-02-18
2021-02-22
  • Swapnil Kotwal

    Swapnil Kotwal - 2021-02-18

    I've used below DiffBuilder using XMLUnit-2

    diff = DiffBuilder.compare(control).withTest(test).checkForSimilar()
    .normalizeWhitespace().ignoreComments()
    .ignoreWhitespace().ignoreElementContentWhitespace()
    .withNodeFilter(node -> (filter(node, attrsToIgnore)))
    .withAttributeFilter(fields -> (filterFields(fields, fieldsToIgnore)))
    .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)).build();
    

    It works well for shuffling the List<> values or random value in List<> as shown below

    <?xml version='1.0' encoding='UTF-8'?>
    <!DOCTYPE ResourceObject PUBLIC "sailpoint.dtd" "sailpoint.dtd">
    <ResourceObject displayName="aggaccnm1" identity="U013JFHQ59D" objectType="account">
      <Attributes>
        <Map>
          <entry key="costCenter" value="1111"/>
          <entry key="department" value="QA"/>
          <entry key="displayName" value="AggACCDN1"/>
          <entry key="groups">
            <value>
              <List>
                <String>S013J6S7STH</String>
                <String>S013S71EMLN</String>
                <String>S013S71GTU6</String>
              </List>
            </value>
          </entry>
        </Map>
      </Attributes>
    </ResourceObject>
    

    But, When I've List < Map {} > it fails.. what can be done to handle both random order of List<String> values as well as List < Map {} > value orders.

    <?xml version='1.0' encoding='UTF-8'?>
    <!DOCTYPE ResourceObject PUBLIC "sailpoint.dtd" "sailpoint.dtd">
    <ResourceObject displayName="aggaccnm1" identity="U013JFHQ59D" objectType="account">
      <Attributes>
        <Map>
          <entry key="costCenter" value="1111"/>
          <entry key="department" value="QA"/>
          <entry key="displayName" value="AggACCDN1"/>
          <entry key="groups">
            <value>
              <List>
                <String>S013J6S7STH</String>
                <String>S013S71EMLN</String>
                <String>S013S71GTU6</String>
              </List>
            </value>
          </entry>
          <entry key="groups_objects">
            <value>
              <List>
                <Map>
                  <entry key="display" value="Agggrp1"/>
                  <entry key="value" value="S013S71EMLN"/>
                </Map>
                <Map>
                  <entry key="display" value="Agggrp5"/>
                  <entry key="value" value="S013S71GTU6"/>
                </Map>
                <Map>
                  <entry key="display" value="Agggrp7"/>
                  <entry key="value" value="S013S71HVU6"/>
                </Map>
              </List>
            </value>
          </entry>
        </Map>
      </Attributes>
    </ResourceObject>
    

    In above example you can notice I've List < Map {} > and my above implementation working well for simple List<> but not for List < Map {} >

    I want to ignore the order of both, someone please let me know how this can be achieved?

    Thanks,
    Swapnil.

     

    Last edit: Swapnil Kotwal 2021-02-18
  • Stefan Bodewig

    Stefan Bodewig - 2021-02-20

    You are using ElementSelectors.byNameAndText which means: when looking at lists of elements, compare those which each other that have the same element name and the same nested text. This works fine for elements like <String>S013J6S7STH</String>.

    In your second example you want to influence which Map elements XMLUnit compares with each other. The Map elements have no nested text at all, so they all have the same nested text and you compare them in-order. I'm not really sure what identifies the Map elements for you - this is something only you will know, XMLUnit cannot guess that either. As a human I can guess that you consider two Map-elements to be "the same" if they share the same value in their nested entry element that has key attribute with the value display. In that case a byXPath element selector probably is a good choice.

    As you need different element selectors for different elements you probably want a conditional builder.

     
  • Swapnil Kotwal

    Swapnil Kotwal - 2021-02-22

    I'm talking about Map { } inside

     <entry key="groups_objects">
            <value>
              <List>
                <Map>
                  <entry key="display" value="Agggrp1"/>
                  <entry key="value" value="S013S71EMLN"/>
                </Map>
                <Map>
                  <entry key="display" value="Agggrp5"/>
                  <entry key="value" value="S013S71GTU6"/>
                </Map>
                <Map>
                  <entry key="display" value="Agggrp7"/>
                  <entry key="value" value="S013S71HVU6"/>
                </Map>
              </List>
            </value>
          </entry>
    
     

    Last edit: Swapnil Kotwal 2021-02-22
  • Stefan Bodewig

    Stefan Bodewig - 2021-02-22

    so am I

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.