Schematron calculation tests for optional elements

Questions about XML that are not covered by the other forums should go here.
Iwicka
Posts: 11
Joined: Thu Nov 21, 2013 3:34 pm

Schematron calculation tests for optional elements

Post by Iwicka »

Hi,

I need to create set of Schematron rules testing calculations in an XML Invoice. The problem is that some of the tested elements are optional and my rules fail when the tested elements are mjissing. How do I specify something like: "test value if the element is present"?

The XML instance excerpt:

Code: Select all

<invoice>
<invoiceLineItem number="1">
<invoicedQuantity>50</invoicedQuantity>
<amountExclusiveAllowancesCharges>500</amountExclusiveAllowancesCharges>
<amountInclusiveAllowancesCharges>455</amountInclusiveAllowancesCharges>
<itemPrice>10</itemPrice>
<invoiceAllowanceChargeAmount>45</invoiceAllowanceChargeAmount>
</invoiceLineItem>
<invoiceLineItem number="2">
<invoicedQuantity>10</invoicedQuantity>
<amountExclusiveAllowancesCharges>150</amountExclusiveAllowancesCharges>
<itemPrice>15</itemPrice>
</invoiceLineItem>
</invoice>
My Schematron checking the calculation:

Code: Select all

<sch:schema xmlns:sch="http://www.ascc.net/xml/schematron">
<sch:pattern name="Check calculation in invoicelineItem">
<sch:rule context="invoiceLineItem">
<sch:assert test="amountExclusiveAllowancesCharges = invoicedQuantity * itemPrice">The amountExclusiveAllowancesCharges calculation is incorrect.</sch:assert>
<sch:assert test="amountInclusiveAllowancesCharges = (invoicedQuantity * itemPrice) - invoiceAllowanceChargeAmount">The amountInclusiveAllowancesCharges calculation is incorrect.</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>
It fails when the amountInclusiveAllowancesCharges and invoiceAllowanceChargeAmount are missing (they are optional).

I'll be grateful for any useful tips,

Ewa
adrian
Posts: 2855
Joined: Tue May 17, 2005 4:01 pm

Re: Schematron calculation tests for optional elements

Post by adrian »

Hi,

If the elements are optional you can check if they do not exist with not(elementName).
e.g.

Code: Select all

<sch:rule context="invoiceLineItem">
<sch:assert test="not(amountExclusiveAllowancesCharges) or amountExclusiveAllowancesCharges = invoicedQuantity * itemPrice">The amountExclusiveAllowancesCharges calculation is incorrect.</sch:assert>
<sch:assert test="not(amountInclusiveAllowancesCharges) or amountInclusiveAllowancesCharges = (invoicedQuantity * itemPrice) - invoiceAllowanceChargeAmount">The amountInclusiveAllowancesCharges calculation is incorrect2.</sch:assert>
</sch:rule>
If you want the code to be more explicit, you can use not(exists(elementName)). However, since exists is an XPath 2.0 function, if you're going to use it, you'll also need to set in Oxygen the Schematron XPath version to 2.0 in Options > Preferences, XML / XML Parser / Schematron.

Regards,
Adrian
Adrian Buza
<oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com
Iwicka
Posts: 11
Joined: Thu Nov 21, 2013 3:34 pm

Re: Schematron calculation tests for optional elements

Post by Iwicka »

Thank you! It really helps :D :D
Post Reply