I have the following code which should add an error if there is an orderEvents element and that element has a child node that is not an orderEvent or empty text. The test cases do a better job of showing what I'm after.
The XPATH expression works in all cases except when there is empty space within the orderEvents element. See test case validVendorPaymentFormat7 below. Here's my XPATH expression.
"./expectedVendorPaymentTransactions/orderEvents/node()[not(self::orderEvent) or self::text()[normalize-space(.)!='']]"
Test Cases:
<TestData>
<TestcaseList>
<Testcase>
<rootIdentifier>validVendorPaymentFormat1</rootIdentifier>
<expectedVendorPaymentTransactions>
<orderEvents></orderEvents>
</expectedVendorPaymentTransactions>
</Testcase>
<Testcase>
<rootIdentifier>validVendorPaymentFormat2</rootIdentifier>
</Testcase>
<Testcase>
<rootIdentifier>validVendorPaymentFormat3</rootIdentifier>
<expectedVendorPaymentTransactions>
</expectedVendorPaymentTransactions>
</Testcase>
<Testcase>
<rootIdentifier>validVendorPaymentFormat4</rootIdentifier>
<expectedVendorPaymentTransactions>
<orderEvents><orderEvent>SOME_EVENT</orderEvent></orderEvents>
</expectedVendorPaymentTransactions>
</Testcase>
<Testcase>
<rootIdentifier>validVendorPaymentFormat5</rootIdentifier>
<expectedVendorPaymentTransactions>
<orderEvents><orderEvent>SOME_EVENT</orderEvent></orderEvents>
</expectedVendorPaymentTransactions>
</Testcase>
<Testcase>
<rootIdentifier>validVendorPaymentFormat6</rootIdentifier>
<expectedVendorPaymentTransactions>
<orderEvents><orderEvent>SOME_EVENT</orderEvent><orderEvent>SOME_EVENT</orderEvent></orderEvents>
</expectedVendorPaymentTransactions>
</Testcase>
<Testcase>
<rootIdentifier>validVendorPaymentFormat7</rootIdentifier>
<expectedVendorPaymentTransactions>
<orderEvents>
<orderEvent>SOME_EVENT</orderEvent>
</orderEvents>
</expectedVendorPaymentTransactions>
</Testcase>
</TestcaseList>
</TestData>
The failing case is validVendorPaymentFormat7
Failure Message:
[exec] Failure:
[exec] Order vendor payments format contains elements other than orderEvent for validVendorPaymentFormat7 ["\n ", "\n "].
[exec] <false> is not true.
Changing the failing case to:
<Testcase>
<rootIdentifier>validVendorPaymentFormat7</rootIdentifier>
<expectedVendorPaymentTransactions>
<orderEvents><orderEvent>SOME_EVENT</orderEvent></orderEvents>
</expectedVendorPaymentTransactions>
</Testcase>
Results in a pass.
Unfortunately on http://www.freeformatter.com/xpath-tester.html test case #7 returns an empty list as expected.
UPDATE - Adding code
Ruby Version: 1.9
irb -v = 0.9.6
Test File:
require 'rexml/document'
xpath = "//expectedVendorPaymentTransactions/orderEvents/node()[not(self::orderEvent) or self::text()[translate(., ' ', '')!='']]"
document = REXML::Document.new <<EOF
<Testcase>
<rootIdentifier>validVendorPaymentFormat7</rootIdentifier>
<expectedVendorPaymentTransactions>
<orderEvents>
<orderEvent>SOME_EVENT</orderEvent>
</orderEvents>
</expectedVendorPaymentTransactions>
</Testcase>
EOF
document2 = REXML::Document.new <<EOF
<Testcase>
<rootIdentifier>validVendorPaymentFormat7</rootIdentifier>
<expectedVendorPaymentTransactions>
<orderEvents><orderEvent>SOME_EVENT</orderEvent></orderEvents>
</expectedVendorPaymentTransactions>
</Testcase>
EOF
puts "1: #{REXML::XPath.match(document, xpath).inspect}"
puts "2: #{REXML::XPath.match(document2, xpath).inspect}"
Output:
irb(main):001:0> load './test/test_rexp.rb'
1: ["\n ", "\n "]
2: []
=> true
Latest Revision of Jens:
irb(main):009:0> load './test/test_rexp.rb'
1: ", "
2: ", "
=> true