I'm using ph-schematron, a Java library that validates XML documents via ISO Schematron:
This library provides 2 ways of XML document validation:
I would love to use the second type, but my Schematron files contain XSLT functions so we MUST use the validation using XSLT and not the pure one.
I have a validation method that has two input paramters:
Now my XSLT file contains lines like this:
<xsl:when test="count(hl7:confidentialityCode[concat(@code,@codeSystem)=doc('include/voc-1.3.6.1.4.1.12559.11.10.1.3.1.42.31-DYNAMIC.xml')//valueSet[1]/conceptList/concept/concat(@code,@codeSystem) or @nullFlavor])>=1" />
And the doc function looks for a folder called 'include' in the home directory of my project instead of the folder relative to the XSLT document (which would be more logic).
Now I got exceptions like:
java.io.FileNotFoundException: C:\LocalData\Development\projectname\include\voc-1.3.6.1.4.1.12559.11.10.1.3.1.42.31-DYNAMIC.xml (The system cannot find the path specified)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:90)
at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:188)
at org.apache.xerces.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
at org.apache.xerces.impl.XMLVersionDetector.determineDocVersion(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at net.sf.saxon.event.Sender.sendSAXSource(Sender.java:451)
at net.sf.saxon.event.Sender.send(Sender.java:153)
at net.sf.saxon.functions.DocumentFn.makeDoc(DocumentFn.java:330)
at net.sf.saxon.functions.Doc.call(Doc.java:138)
at net.sf.saxon.functions.Doc.call(Doc.java:24)
at net.sf.saxon.expr.FunctionCall.iterate(FunctionCall.java:546)
at net.sf.saxon.expr.Expression.evaluateItem(Expression.java:773)
at net.sf.saxon.expr.SimpleStepExpression.iterate(SimpleStepExpression.java:108)
at net.sf.saxon.expr.SlashExpression.iterate(SlashExpression.java:868)
at net.sf.saxon.expr.SlashExpression.iterate(SlashExpression.java:868)
at net.sf.saxon.expr.SlashExpression.iterate(SlashExpression.java:868)
at net.sf.saxon.expr.SlashExpression.iterate(SlashExpression.java:868)
at net.sf.saxon.value.MemoClosure.iterate(MemoClosure.java:109)
at net.sf.saxon.expr.VariableReference.iterate(VariableReference.java:482)
at net.sf.saxon.expr.GeneralComparison.effectiveBooleanValue(GeneralComparison.java:621)
at net.sf.saxon.expr.OrExpression.effectiveBooleanValue(OrExpression.java:131)
at net.sf.saxon.expr.FilterIterator$NonNumeric.matches(FilterIterator.java:198)
at net.sf.saxon.expr.FilterIterator.getNextMatchingItem(FilterIterator.java:81)
at net.sf.saxon.expr.FilterIterator.next(FilterIterator.java:64)
at net.sf.saxon.functions.Exists$1.effectiveBooleanValue(Exists.java:67)
at net.sf.saxon.expr.instruct.Choose.choose(Choose.java:865)
at net.sf.saxon.expr.instruct.Choose.processLeavingTail(Choose.java:840)
at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:653)
at net.sf.saxon.expr.instruct.TemplateRule.applyLeavingTail(TemplateRule.java:353)
at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:456)
at net.sf.saxon.trans.TextOnlyCopyRuleSet.process(TextOnlyCopyRuleSet.java:65)
at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:433)
at net.sf.saxon.expr.instruct.ApplyTemplates.apply(ApplyTemplates.java:298)
at net.sf.saxon.expr.instruct.ApplyTemplates.processLeavingTail(ApplyTemplates.java:255)
at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:653)
at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:149)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:364)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:311)
at net.sf.saxon.expr.instruct.TemplateRule.applyLeavingTail(TemplateRule.java:353)
at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:456)
at net.sf.saxon.Controller.transformDocument(Controller.java:2321)
at net.sf.saxon.Controller.transform(Controller.java:1892)
at net.sf.saxon.s9api.XsltTransformer.transform(XsltTransformer.java:579)
at net.sf.saxon.jaxp.TransformerImpl.transform(TransformerImpl.java:185)
at com.helger.schematron.xslt.AbstractSchematronXSLTBasedResource.applySchematronValidation(AbstractSchematronXSLTBasedResource.java:273)
at com.helger.schematron.xslt.AbstractSchematronXSLTBasedResource.applySchematronValidationToSVRL(AbstractSchematronXSLTBasedResource.java:288)
at com.helger.schematron.xslt.AbstractSchematronXSLTBasedResource.getSchematronValidity(AbstractSchematronXSLTBasedResource.java:197)
at com.helger.schematron.AbstractSchematronResource.getSchematronValidity(AbstractSchematronResource.java:210)
at epsos.ccd.posam.tm.util.NewSchematronValidator.doValidate(NewSchematronValidator.java:47)
at epsos.ccd.posam.tm.util.NewSchematronValidator.validate(NewSchematronValidator.java:39)
at epsos.ccd.posam.tm.util.SchematronValidatorTest.testValidationNew(SchematronValidatorTest.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
How can I force the doc function to look at the include folder in the same directory as the XSLT file and not in the root of my Java Project?
I found a solution:
I defined my own implementation of an URIResolver, that will be used as an XSLT processor internally by ph-schematron:
class ClasspathResourceURIResolver implements URIResolver {
@Override
public Source resolve(String href, String base) throws TransformerException {
return new StreamSource(this.getClass().getClassLoader().getResourceAsStream(href));
}
This URIResolver is then set to the SchematronResourceXSLT:
IReadableResource readableResource = new ReadableResourceInputStream(new FileInputStream(schematronFile));
SchematronResourceXSLT schematronResourceXslt = new SchematronResourceXSLT(readableResource);
schematronResourceXslt.setURIResolver(new ClasspathResourceURIResolver());
Next we can check if the schematron file is valid and check the validity of an XML document:
if (!schematronResourceXslt.isValidSchematron())
throw new IllegalArgumentException ("Invalid Schematron!");
final StreamSource xmlSource = new StreamSource(xmlFile);
final EValidity schematronValidity = schematronResourceXslt.getSchematronValidity(xmlSource);
And now he manages to retrieve the relative paths in the XSLT file.
Hope this can help someone else
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With