Jak vypadá ukázka minimálního příkladu validace v jazyce Java?
Předpokládejme, že validační X-definice se nachází na cestě C:/xdef/validation.xdef a xml dokument, který chceme validovat, se nachází na cestě C:/data/document.xml.
package cz.syntea.skp.slp2.lp.epemog; import cz.syntea.common.xml.KXmlUtils; import cz.syntea.xd.XDDocument; import cz.syntea.xd.XDFactory; import cz.syntea.xd.XDPool; import org.w3c.dom.Element; import java.io.File; public class XdefValidate { public static void main(String[] args) { // creation of xdPool from xdefinition XDPool xdPool = XDFactory.genXDPool(null, "C:/xdef/validation.xdef", null); // obtain xdDocument from xdPool for one validation XDDocument xdDocument = xdPool.createXDDocument(); // validation of the file content. If the content is not valid, it throws an error Element result = xdDocument.xparse(new File("C:/data/document.xml"), null); // print out the input as a string System.out.println(KXmlUtils.nodeToString(result, true)); } }
Jak mohu získat logy z validace, aniž by mi při tom metoda XDDocument.xparse() nevyhodila chybu?
Na ukládání informací o průběhu metody xparse se používá objekt ArrayReporter, který je možné použít v metodě xparse. Do ArrayReporteru se uloží informace v textové podobě na úrovních varování/chyba, které se dají dále programové zpracovat.
package cz.syntea.skp.slp2.lp.epemog; import cz.syntea.common.sys.ArrayReporter; import cz.syntea.common.sys.Report; import cz.syntea.common.xml.KXmlUtils; import cz.syntea.xd.XDDocument; import cz.syntea.xd.XDFactory; import cz.syntea.xd.XDPool; import org.w3c.dom.Element; import java.io.File; public class XdefValidate { public static void main(String[] args) { // creation of xdPool from xdefinition XDPool xdPool = XDFactory.genXDPool(null, "C:/xdef/validation.xdef", null); // obtain xdDocument from xdPool for one validation XDDocument xdDocument = xdPool.createXDDocument(); // validation of the file content. If the content is not valid, it throws an error ArrayReporter reporter = new ArrayReporter(); Element result = xdDocument.xparse(new File("C:/data/document.xml"), reporter); if (reporter.errorWarnings()) { // print the protocol from the validation Report rep; while ((rep = reporter.getReport()) != null) { System.err.println(rep.toString()); } System.exit(-1); } // print the input xml System.out.printf(KXmlUtils.nodeToString(result, true)); } }
Jaké jsou rozdíly mezi skriptem, externí metodou a deklarovanou metodou?
Externí metody a deklarované metody jsou Java kód, skript je vlastní skript xdefinic X-Script. Externí metody se deklarují v Java třídách v externích souborech, deklarované metody se definují ve vlastním souboru xdefinice pomocí klíčového slova xd:declaration. V druhém případě je potom nutné deklarovat signatury metod v hlavičce xdefinice pod klíčovým slovem xd:methods. Tímto způsobem je ovšem také možné deklarovat typy nebo proměnné. X-Script je deklarovaný také uvnitř xdefinice pod klíčovým slovem xd:script. Může volat vestavěné metody xdefinic, externí a deklarované metody.
Jak lze přistupovat z externích metod k zpracovávanému xml dokumentu?
Do signatury externí metody přidáme parametr xnode typu XXNode, který představuje objektovou reprezentaci uzlu v xml dokumentu, který se právě zpracovává.
public static void myPrint(XXNode xnode, String output) { String lp = xnode.getXXElement().getAttribute("lp"); System.out.printf("Info=%s; Licence plate=%s", output, lp); }
Při validaci xml mi nestačí standardní datové typy zavedené v xdefinici. Je možné definovat vlastní datový typ?
Parser xdefinic obsahuje velké množství typů dat, které lze použít k popisu atributů a hodnot uzlu, v některých případech je ale vhodné si nadefinovat vlastní datový typ, ať už pro speciální účel, nebo pro zpřehlednění samotné xdefinice. Nové datové typy se definují pomocí klíčového slova xd:declarations.
<xd:def xmlns:xd = "http://www.syntea.cz/xdef/2.0" xd:name = "Vehicles" xd:root = "Vehicles"> <Vehicles> <Car xd:script = "occurs 0.." Type = "required carType()" LicencePlate = "required lp(7)" /> </Vehicles> <xd:declaration> /* own type derived from another */ type carType list('SEDAN', 'WAGON', 'HATCHBACK', 'SUV'); /* own type from scratch */ boolean lp(int len) { String text = getText(); if (text.length() != len) { return error(text + " does not meet the conditions. " + len + " character are required."); } return true; } </xd:declaration> </xd:def>
V X-Definici jsou použity datové typy, které plně nekorespondují s datovými typy v Javě. Např. datový typ int resp. typová metoda int() v X-Skriptu X-Definice pracuje ve skutečnosti s 64 bitovými celými čísly a odpovídá tak datovému typu long v Javě.
Tuto skutečnost je nutné mít na zřeteli právě při implementaci externích metod a při předávání parametrů mezi X-Definicí a externí metodou v Java třídě. Řešením je předefinovat v externí java funkci typ parametru z int na long.