Menu

XMLUnit-2 ignore certain nested XML elements

Help
2020-04-10
2020-08-30
  • Swapnil Kotwal

    Swapnil Kotwal - 2020-04-10

    My XML is little complex and I've to ignore certain entry from the comparison, how would I able to achieve it ?

    <?xml version='1.0' encoding='UTF-8'?>
    <!DOCTYPE ResourceObject PUBLIC "my_corp.dtd" "my_corp.dtd">
    <ResourceObject displayName="TESTNGAD\AggUserFSP test" identity="FooBar" objectType="account" uuid="{97182a65-61f2-443c-b0fa-477d0821d8c4}">
       <Attributes>
         <Map>
           <entry key="accountFlags">
             <value>
               <List>
                 <String>Normal User Account</String>
                 <String>Password Cannot Expire</String>
               </List>
             </value>
           </entry>
           <entry key="homePhone" value="6555"/>
           <entry key="l" value="Pune"/>
           <entry key="memberOf">
             <value>
               <List>
                 <String>CN=FSPGRP2,OU=ADAggF,OU=unittests2,DC=AUTODOMAIN,DC=LOCAL</String>
                 <String>CN=FSPGRP1,OU=ADAggF,OU=unittests2,DC=AUTODOMAIN,DC=LOCAL</String>
                 <String>CN=LocalAggFrame,OU=FSPAggeFrame,OU=unittests,DC=TestNGAD,DC=local</String>
               </List>
             </value>
           </entry>
           <entry key="objectClass">
             <value>
               <List>
                 <String>top</String>
                 <String>person</String>
                 <String>organizationalPerson</String>
                 <String>user</String>
               </List>
             </value>
           </entry>
           <entry key="sn" value="test"/>
           <entry key="st" value="MH"/>
           <entry key="streetAddress" value="SB ROAD"/>
           <entry key="title" value="QA"/>
           <entry key="userPrincipalName" value="AggUserFSP test@TestNGAD.local"/>
         </Map>
       </Attributes>
     </ResourceObject>
    

    I tried

    Diff diff = DiffBuilder
                 .compare(control)
                 .withTest(test)
                 .checkForSimilar().checkForIdentical()
                 .normalizeWhitespace()
                 .ignoreComments()
                 .ignoreWhitespace()
                 .withNodeFilter(node -> !(node.getNodeName().equals("accountFlags") ||
                                node.getNodeName().equals("homePhone"))).build();
    

    But, it is not working. How should I ignore some XML entry here?

     

    Last edit: Swapnil Kotwal 2020-04-15
  • Stefan Bodewig

    Stefan Bodewig - 2020-04-11

    Neither accountFlags nor homePhone are element names, so your filter will not match anything.

    Your NodeFilter must return true unless all of the following conditions are met

    1. node is actually an Element
    2. node has an attribute named "key"
    3. the value of this attribute is either accountFralgs or homePhone
    private boolean filter(final Node n) {
        if (n instanceof Element) {
            final String attrValue = ((Element) n).getAttibute("key");
            // attrValue is th eempty string if the attribute is missing
            return !("accountFlags".equals(attrValue) || "homePhone".equals(attrValue));
        }
        return true;
    }
    
     
    • Swapnil Kotwal

      Swapnil Kotwal - 2020-04-11

      Thank you for the clarification Stefan

      On Sat, 11 Apr, 2020, 2:17 PM Stefan Bodewig, bodewig@users.sourceforge.net
      wrote:

      Neither accountFlags nor homePhone are element names, so your filter will
      not match anything.

      Your NodeFilter must return true unless all of the following conditions
      are met

      1. node is actually an Element
      2. node has an attribute named "key"
      3. the value of this attribute is either accountFralgs or homePhone

      private boolean filter(final Node n) {
      if (n instanceof Element) {
      final String attrValue = ((Element) n).getAttibute("key");
      // attrValue is th eempty string if the attribute is missing
      return !("accountFlags".equals(attrValue) || "homePhone".equals(attrValue));
      }
      return true;
      }


      XMLUnit-2 ignore certain nested XML elements
      https://sourceforge.net/p/xmlunit/discussion/73274/thread/5481136c30/?limit=25#d0fd


      Sent from sourceforge.net because you indicated interest in
      https://sourceforge.net/p/xmlunit/discussion/73274/

      To unsubscribe from further messages, please visit
      https://sourceforge.net/auth/subscriptions/

       
  • Stefan Bodewig

    Stefan Bodewig - 2020-04-13

    assuming https://sourceforge.net/p/xmlunit/discussion/73274/thread/b01a104e75/#6e65 was meant to go here:
    You really need to answer to yourself what it is that makes you know which entrys to compare to each other. Don't thnk in terms of XPaths, think in terms of your logical data model. And once you've understood what is important in your data model, then - and only then - start thinking about how this translates to XML structure.
    It is not unlikely that implementing a NodeFilter or ElementSelector yourself rather than using sometihig built-in (like XPath) is the more sensible option.

     
  • Swapnil Kotwal

    Swapnil Kotwal - 2020-04-15

    Thanks Stefan for the response. Sorry, I'm just putting baby steps and messed up certain things.

    From serverResponseXML I might have some entrys I want to ignore during comparison and I might specify partial localTestXML which not necessarily should have all entrys from serverResponseXML (i.e. I want to validate with partial local XML(It can be partial XML or as complete as serverResponseXML) with some additional filters)

    What would be best way to achive it?

     
    • Stefan Bodewig

      Stefan Bodewig - 2020-04-15

      I'm afraid this is something that is easier to do for humans than to implement in code.

      When you look at the serverResponseXML how do you know which parts you want to compare and which are not necessary? Is it as simple as "any element that's not in localTestXML is irrelevant" or could this hide errors of extra elements suddenly appearing in unexpected places?

       
  • Swapnil Kotwal

    Swapnil Kotwal - 2020-04-15

    I already have implemented it using CSV but my data is complex so I turned to XMLUnit library.

    My server can returns data of 100s of Users/Groups etc and I've to validate some of them.

    Considering above given XML, I can specify data into CSV as below

    identity,accountFlags,homePhone
    "FooBar",(Not_to_Validate),6555
    "FooBar1",["list data1","list data2"],6555
    

    Here , you can notice, in first row of CSV

    1. I mentioned only very few partials entrys to validate and also ignored (filtered out) accountFlags=(Not_to_Validate). I can convert CSV to Map and XML entry data to Map and very easily comparing it.

    In second row,

    1. I mentioned partials entrys to validate but no filter.

    So, ultimately I want to give user following freedoms

    1. User can compare whole XML as it is with server response
    2. User can compare whole XML with server response but just ignore certain dyanamicentry node as those might be dynamic and not possible to compare with static data
    3. User can compare partial XML entry
    4. User can compare partial XML entry and also ignore certain dyanamicentry during comparison.

    It was very easy with CSVs but CSV have lot of manual work to convert XML data to CSVs and many more problems.

    XMLUnit library solved all above mentioned problem and also problems those can't be solved using CSV except partial XML data validation (even I achived node filteration)

    Won't it possible to validate only given partial XML data and ignoring anything else sent by the server?

     

    Last edit: Swapnil Kotwal 2020-04-15
  • Stefan Bodewig

    Stefan Bodewig - 2020-04-20

    I'm sorry if I seem to be a bit slow on this but I believe I still don't undertstand what you actually mean by partial XML data validation.

    This is waht I'm guessing: You've got a document that describes your tests as a sparse XML document. You are not interested in parts of the server response that are not part of the sparse tree in your document.

    To achive this, you will need a NodeFilter and may need to combine it with something loke an ElementSelector to figure out which parts of the tree to ignore. You probably also need an AttributeFilter to ignore attributes you are not interested in. I'm afraid I don't understand where this part is different from "just filtering".

    If after this certain differences remain that you are not interested in - say element order - you will also need a DifferenceEvaluator.

    And most likely none of the built-in implementations will do.

     
  • Swapnil Kotwal

    Swapnil Kotwal - 2020-04-20

    Thanks Stefan,

    Assume, I have localTestXML as

    <?xml version='1.0' encoding='UTF-8'?>
    <!DOCTYPE ResourceObject PUBLIC "my_corp.dtd" "my_corp.dtd">
    <ResourceObject displayName="TESTNGAD\AggUserFSP test" identity="FooBar" objectType="account" uuid="{97182a65-61f2-443c-b0fa-477d0821d8c4}">
       <Attributes>
           </entry>
           <entry key="homePhone" value="6555"/>
           <entry key="l" value="Pune"/>
           <entry key="memberOf">
         </Map>
       </Attributes>
    </ResourceObject>
    

    But, server Response can keep on increasing. It might add newer entrys going forward. Assume that it added new entrys as below

    <?xml version='1.0' encoding='UTF-8'?>
    <!DOCTYPE ResourceObject PUBLIC "my_corp.dtd" "my_corp.dtd">
    <ResourceObject displayName="TESTNGAD\AggUserFSP test" identity="FooBar" objectType="account" uuid="{97182a65-61f2-443c-b0fa-477d0821d8c4}">
       <Attributes>
           </entry>
           <entry key="homePhone" value="6555"/>
           <entry key="l" value="Pune"/>
           <entry key="memberOf">
           <entry key="Foo" value="SB ROAD"/>
           <entry key="Bar" value="QA"/>
         </Map>
       </Attributes>
    </ResourceObject>
    

    After certain intervals it can add few more data to the list... so here I don't even know what nodeFilter can filter...

    I'm just interested in the Whatever initial localTestXML data that should match with the server responses and if there is anything extra that can be gracefully ignored?🤔

     
  • Stefan Bodewig

    Stefan Bodewig - 2020-05-12

    Sorry I was busy elsewhere and forgot to answer here.

    Starting out with you ElementSelector that would use byNameAndAttributes("key") for entry - and whatever else is needed, you'd only end up with CHILD_LOOKUP differences for things the server has added and CHILD_NODELIST_LENGTH. The later could be downgraded easily in a DifferenceEvaluator using DifferenceEvaluators.downgradeDifferencesToSimilar. For the CHILD_LOOKUP you'll have to write a small DifferenceEvaluator yourself which would return EQUAL or SIMILAR if the difference is of type CHILD_LOOKUP and the target Node is non-null on the side of the server's response - i.e. the server contains elements your local data doesn't.

     
    • Swapnil Kotwal

      Swapnil Kotwal - 2020-05-16

      Thanks you Stefan, this will help :)

      On Tue, May 12, 2020 at 10:27 PM Stefan Bodewig bodewig@users.sourceforge.net wrote:

      Sorry I was busy elsewhere and forgot to answer here.

      Starting out with you ElementSelector that would use
      byNameAndAttributes("key") for entry - and whatever else is needed, you'd
      only end up with CHILD_LOOKUP differences for things the server has added
      and CHILD_NODELIST_LENGTH. The later could be downgraded easily in a
      DifferenceEvaluator using
      DifferenceEvaluators.downgradeDifferencesToSimilar. For the CHILD_LOOKUP
      you'll have to write a small DifferenceEvaluator yourself which would
      return EQUAL or SIMILAR if the difference is of type CHILD_LOOKUP and the
      target Node is non-null on the side of the server's response - i.e. the
      server contains elements your local data doesn't.


      XMLUnit-2 ignore certain nested XML elements
      https://sourceforge.net/p/xmlunit/discussion/73274/thread/5481136c30/?limit=25#5f72


      Sent from sourceforge.net because you indicated interest in
      https://sourceforge.net/p/xmlunit/discussion/73274/

      To unsubscribe from further messages, please visit
      https://sourceforge.net/auth/subscriptions/

      --
      Swapnil

       
  • Aashay Pilivkar

    Aashay Pilivkar - 2020-08-25

    Hi,

    I am facing the same issue.
    I am trying to compare actual and expected XML responses using Java.
    For that I am using DiffBuilder. I want to ignore few date-time attributes from root node while comparing the xmls. However when I pass the with NodeFilter(node -> !node.getNodename(). equals("Nodename") ) it ignores complete xml.
    Could you please let me know the work around for the issue?
    Thanks in advance.

     
    • Stefan Bodewig

      Stefan Bodewig - 2020-08-30

      You don't want to ignore the element at all, you want to ignore certain attributes on them. So AttributeFilter is what you want to use rather than NodeFilter.

       

Log in to post a comment.

MongoDB Logo MongoDB