views:

93

answers:

3

Given an xml document like

<root>
  <row>
    <a>2</a>
    <b>1</b>
    <c>8</c>
  </row>
  <row>
    <b>5</b>
    <a>2</a>
    <c>8</c>
  </row>
  <row>
    <a>2</a>
    <c>8</c>
    <b>6</b>
  </row>
</root>

Is there an easy way to assert that the XML document is sorted on element B in XMLUnit

Edit: I have an odd problem with a piece of software that I can not change where the value of the XML tags in any given node needs to be in a specific order. I'd like it for my test harness to enforce this set of rules before any other validation.

+1  A: 

You can build an assertion around an XPath selection.

Probably the simplest way would be to use the XPath expression /root/row/b, request the NODESET result type, then copy the text from each result node into a List structure. You can assert that the text in that list is equal to an "expected" list created with the Arrays.asList() method (I'm assuming you're using Java).

Anon
This was what I was doing and I wasn't happy with it. For starters, there was too much code that was specific to a particular test and more code that might have to change as my code changed.
sal
+1  A: 

If you can execute XQuery, then the XQuery assertion:

every $i in (1 to count ($x/row) - 1)
satisfies 
   let $j :=  $i + 1   
   return number($x/row[$i]/b) <= number($x/row[$j]/b)

where $x is the document, is true if the rows are in ascending order of b, false otherwise

Chris Wallace
I'm too junior to comment on Dimitre's neat answer but shouldn't it benot($x//b[number(.) > following::b/number(.)]) for this numeric data and isnt this O N^2 since every b is compared with all the following b's?
Chris Wallace
Chris, you're right about number()
sal
+1  A: 

Use the value of the following simple XPath 1.0 expression:

not(//b[. > following::b])

Dimitre Novatchev
This is almost what I wanted. I got my solution after looking at this. Thanks!
sal
Hey sal, what IS your solution?
belwood
@belwood: @sal says that he put this XPath expression in his code -- probably the real column names were different. If you have the same problem, this answer should get you going.
Dimitre Novatchev