- From: Andrew Welch <andrew.j.welch@gmail.com>
- Date: Tue, 5 Jun 2007 16:44:39 +0100
- To: xmlschema-dev@w3.org
xchecker is a little utility I've written that (amongst other things) allows you to embed XPath 2.0 in XML Schema. http://xchecker.sf.net/ The xchecker processor implements the JAXP schema interfaces, using the underlying JAXP schema processor to do the validation. You can check anything you can you can write an XPath for. For example, if you had the XML: <c:stock xmlns:c="http://company.com"> <c:item id="001" price="1.50" quantity="6" total="9.00"/> <c:item id="002" price="2" quantity="0"/> <c:item id="003" price="3" quantity="1" total="3"/> </c:stock> ...and you wanted to ensure only items with a quantity > 0 had a total attribute, and that the total was correct, you could use: <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xck="http://xchecker.sf.net/" targetNamespace="http://company.com" xmlns:c="http://company.com"> <!-- The xchecker XPath checks can be used in <xs:appinfo> elements. The context node is the root node, all XPaths are global. --> <xs:annotation> <xs:appinfo> <!-- Check that all <c:item>'s with quantity greater than zero also have a @total (by inverting it and checking that there doesn't exist a <c:item> with a @quantity of zero and a total) --> <xck:check>not(exists(//c:item[number(@quantity) eq 0][@total]))</xck:check> <!-- Check that the @quantity is always correct (price * quantity) and report a helpful message if it isn't --> <xck:check>for $x in //c:item[@total] return if ($x[number(@total) ne @price * @quantity]) then concat('Item ', $x/@id, ' has an incorrect total') else 'true'</xck:check> </xs:appinfo> </xs:annotation> <xs:element name="stock"> <xs:complexType> <xs:sequence> <xs:element ref="c:item" maxOccurs="3"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="item"> <xs:complexType> <xs:attribute name="id" type="xs:string" use="required"/> <xs:attribute name="price" type="xs:decimal" use="required"/> <xs:attribute name="quantity" type="xs:nonNegativeInteger" use="required"/> <xs:attribute name="total" type="xs:decimal"/> </xs:complexType> </xs:element> </xs:schema> To apply this schema from JAXP, create an XCheckerSchemaFactory and go from there: SchemaFactory schemaFactory = new XCheckerSchemaFactory(); Schema schema = schemaFactory.newSchema(xsd); Validator validator = schema.newValidator(); validator.validate(new StreamSource(xml)); Saxon is used as the XPath engine, and as the preferred Schema processor if its available. More information is available at http://xchecker.sf.net/ cheers andrew
Received on Tuesday, 5 June 2007 15:44:46 UTC