phax / ph-schematron

Java Schematron library that supports XSLT and native application
Apache License 2.0
112 stars 36 forks source link

Can I use ph-schematron by CLI or with Apache Ant #39

Closed stefan-jung closed 7 years ago

stefan-jung commented 7 years ago

Can I use ph-schematron by command line interfache (e.g. like crux) or has anybody written an Apache Ant task?

phax commented 7 years ago

Hi. I'm not aware of any ANT task - I just have a Maven plugin :) Can you point me to some tutorial where this is explained - should be no problem, right?

phax commented 7 years ago

Okay - I'm using http://ant.apache.org/manual/tutorial-writing-tasks.html as the basis.

stefan-jung commented 7 years ago

You can define a new Ant task with a <taskdef>, see taskdef.

Example for setting up the <scp> task using the ant-jsch lib and the jsch lib

<?xml version="1.0" encoding="UTF-8"?>
<project basedir="." default="copy">

  <!-- Create path -->
  <path id="jsch.path">
    <pathelement location="lib/ant-jsch-1.9.2.jar"/>
    <pathelement location="lib/jsch-0.1.54.jar"/>
  </path>

  <!-- Define <scp> task -->
  <taskdef name="scp" classname="org.apache.tools.ant.taskdefs.optional.ssh.Scp" classpathref="jsch.path" />
  <taskdef name="sshexec" classname="org.apache.tools.ant.taskdefs.optional.ssh.SSHExec" classpathref="jsch.path" />

  <target name="copy">
    <!-- Copy a single local file to a remote machine using key base authentication. -->
    <scp file="myfile.txt"
      todir="user@somehost:/home/chuck" 
      keyfile="${user.home}/.ssh/id_dsa"
      passphrase="my extremely secret passphrase"
    />
  </target>

</project>
phax commented 7 years ago

Perfect - thanks. Btw. can you beta test what I do here? I'm not an ANT user (but I was) and you're probably much quicker than I am :)

stefan-jung commented 7 years ago

Sure :), please just give me a short instruction what I should download/build/test.

phax commented 7 years ago

Here are binary SNAPSHOTS: https://oss.sonatype.org/content/repositories/snapshots/com/helger/ph-schematron-ant-task/4.2.3-SNAPSHOT/ https://oss.sonatype.org/content/repositories/snapshots/com/helger/ph-schematron/4.2.3-SNAPSHOT/ Additionally you need:

-> Okay that looks a bit complicated - I will see whether I can build a fat JAR...

phax commented 7 years ago

Excellent - now there is a fat JAR available: https://oss.sonatype.org/content/repositories/snapshots/com/helger/ph-schematron-ant-task/4.2.3-SNAPSHOT/ - should do the trick. Please try sthg like this:

NOTE please wait for SNAPSHOT "-4" - there was a missing default value in "-3" version

<?xml version="1.0" encoding="UTF-8"?>
<project basedir="." default="copy">
  <!-- Create path -->
  <path id="phsch.path">
    <pathelement location="lib/ph-schematron-ant-task-4.2.3-20170503.140331-3-jar-with-dependencies.jar"/>
  </path>
  <!-- Define <schematron> task -->
  <taskdef name="schematron" classname="com.helger.schematron.ant.Schematron" classpathref="phsch.path" />
  <target name="check">
    <!-- Check a directory -->
    <schematron schematronFile="myfile.txt"
                xmlDirectory="test-files/xml" 
    />
  </target>
</project>
stefan-jung commented 7 years ago

Thank you for implementing this so fast! 😄

💡 Suggestion for Improvement

It would be nice, if it would support Resource Collections (<fileset>, etc.), e.g. like the <copy> task, see Copy Task. This would be "the Ant way" to include and exclude resources (what you currently do with xmlDirectory).

<copy todir="../dest/dir">
  <fileset dir="src_dir">
    <exclude name="**/*.java"/>
  </fileset>
</copy>
phax commented 7 years ago

So it works?? Great :) Well I basically took the Maven plugin and changed the way parameters are provided. Before I add the fileset, I need to handle #38 so that it is available in Maven and in Ant solution..

stefan-jung commented 7 years ago

Wait, not so fast. I'll try it this evening.

phax commented 7 years ago

No worries - take your time. I will check the fileset stuff also tomorrow. Thanks for the input!

stefan-jung commented 7 years ago

Fails with:

check:
[schematron] SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
[schematron] SLF4J: Defaulting to no-operation (NOP) logger implementation
[schematron] SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
[schematron] Successfully parsed Schematron file '/home/stefan/Schreibtisch/schematron-test/topic.sch'
[schematron] Validating XML file '/home/stefan/Schreibtisch/schematron-test/build.xml' against Schematron rules from '/home/stefan/Schreibtisch/schematron-test/topic.sch' expecting success
[schematron] Validating XML file '/home/stefan/Schreibtisch/schematron-test/topic.xml' against Schematron rules from '/home/stefan/Schreibtisch/schematron-test/topic.sch' expecting success

BUILD FAILED
/home/stefan/Schreibtisch/schematron-test/build.xml:13: Exception validating XML '/home/stefan/Schreibtisch/schematron-test/topic.xml' against Schematron rules from '/home/stefan/Schreibtisch/schematron-test/topic.sch'

I used the ph-schematron-ant-task-4.2.3-20170503.152827-6-jar-with-dependencies.jar

stefan-jung commented 7 years ago

Regarding the fileset stuff: It would also give the flexibility to check XML files with different file endings, e.g. DITA or XHTML files.

phax commented 7 years ago

filesets are a pain in the ass. No default resolution available..... Anyway I managed to use them, so that they work with filesets at least.

I used the following example to test:

<?xml version="1.0" encoding="UTF-8"?>
<project basedir="." default="check">
  <!-- Create path -->
  <path id="phsch.path">
    <fileset dir="../../../../target">
        <include name="*-jar-with-dependencies.jar"/>
    </fileset>
  </path>
  <!-- Define <schematron> task -->
  <taskdef name="schematron" classname="com.helger.schematron.ant.Schematron" classpathref="phsch.path" />
  <target name="check">
    <schematron schematronFile="sample_schematron.sch" expectSuccess="true">
      <fileset dir="xml">
        <include name="*.xml" />
        <exclude name="err*.xml" />
      </fileset>
    </schematron>
    <schematron schematronFile="sample_schematron.sch" expectSuccess="false">
      <fileset dir="xml">
        <include name="err*.xml" />
      </fileset>
    </schematron>
  </target>
</project>
stefan-jung commented 7 years ago

@phax, have you already created a new fat jar?

phax commented 7 years ago

Version should be -7 at https://oss.sonatype.org/content/repositories/snapshots/com/helger/ph-schematron-ant-task/4.2.3-SNAPSHOT/ - I think they use UTC timestamps :)

And this is done automagitally by Travis so don't blame me ;-)

stefan-jung commented 7 years ago
check:
[schematron] Successfully parsed Schematron file '/home/stefan/Schreibtisch/schematron-test/topic.sch'
[schematron] Validating XML file '/home/stefan/Schreibtisch/schematron-test/topic.dita' against Schematron rules from 'topic.sch' expecting success
[schematron] [main] ERROR com.helger.xml.sax.LoggingSAXErrorHandler - [fatal_error] @ file:/home/stefan/Schreibtisch/schematron-test/topic.dita(2:67) [SAX] Externe DTD: Lesen von externer DTD "topic.dtd" nicht erfolgreich, da "file"-Zugriff wegen der von der Eigenschaft "accessExternalDTD" festgelegten EinschrÀnkung nicht zulÀssig ist. (org.xml.sax.SAXParseException: Externe DTD: Lesen von externer DTD "topic.dtd" nicht erfolgreich, da "file"-Zugriff wegen der von der Eigenschaft "accessExternalDTD" festgelegten EinschrÀnkung nicht zulÀssig ist.)
[schematron] [main] ERROR com.helger.commons.callback.exception.LoggingExceptionCallback - [error] @ file:/home/stefan/Schreibtisch/schematron-test/topic.dita(2:67) [SAX] Externe DTD: Lesen von externer DTD "topic.dtd" nicht erfolgreich, da "file"-Zugriff wegen der von der Eigenschaft "accessExternalDTD" festgelegten EinschrÀnkung nicht zulÀssig ist. (org.xml.sax.SAXParseException: Externe DTD: Lesen von externer DTD "topic.dtd" nicht erfolgreich, da "file"-Zugriff wegen der von der Eigenschaft "accessExternalDTD" festgelegten EinschrÀnkung nicht zulÀssig ist.)
[schematron] org.xml.sax.SAXParseException; systemId: file:/home/stefan/Schreibtisch/schematron-test/topic.dita; lineNumber: 2; columnNumber: 67; Externe DTD: Lesen von externer DTD "topic.dtd" nicht erfolgreich, da "file"-Zugriff wegen der von der Eigenschaft "accessExternalDTD" festgelegten EinschrÀnkung nicht zulÀssig ist.
[schematron]    at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:257)
[schematron]    at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:339)
[schematron]    at com.helger.xml.serialize.read.DOMReader.readXMLDOM(DOMReader.java:331)
[schematron]    at com.helger.xml.serialize.read.DOMReader.readXMLDOM(DOMReader.java:181)
[schematron]    at com.helger.xml.serialize.read.DOMReader.readXMLDOM(DOMReader.java:174)
[schematron]    at com.helger.schematron.SchematronResourceHelper.getNodeOfSource(SchematronResourceHelper.java:114)
[schematron]    at com.helger.schematron.pure.SchematronResourcePure.applySchematronValidationToSVRL(SchematronResourcePure.java:417)
[schematron]    at com.helger.schematron.ant.Schematron._performValidation(Schematron.java:265)
[schematron]    at com.helger.schematron.ant.Schematron.execute(Schematron.java:420)
[schematron]    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:293)
[schematron]    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[schematron]    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[schematron]    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[schematron]    at java.lang.reflect.Method.invoke(Method.java:498)
[schematron]    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
[schematron]    at org.apache.tools.ant.Task.perform(Task.java:348)
[schematron]    at org.apache.tools.ant.Target.execute(Target.java:435)
[schematron]    at org.apache.tools.ant.Target.performTasks(Target.java:456)
[schematron]    at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1405)
[schematron]    at org.apache.tools.ant.Project.executeTarget(Project.java:1376)
[schematron]    at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
[schematron]    at org.apache.tools.ant.Project.executeTargets(Project.java:1260)
[schematron]    at org.apache.tools.ant.Main.runBuild(Main.java:857)
[schematron]    at org.apache.tools.ant.Main.startAnt(Main.java:236)
[schematron]    at org.apache.tools.ant.launch.Launcher.run(Launcher.java:287)
[schematron]    at org.apache.tools.ant.launch.Launcher.main(Launcher.java:113)

BUILD FAILED
/home/stefan/Schreibtisch/schematron-test/build.xml:13: Exception validating XML '/home/stefan/Schreibtisch/schematron-test/topic.dita' against Schematron rules from 'topic.sch'. Technical details: SAXParseException - Externe DTD: Lesen von externer DTD "topic.dtd" nicht erfolgreich, da "file"-Zugriff wegen der von der Eigenschaft "accessExternalDTD" festgelegten EinschrÀnkung nicht zulÀssig ist.

Total time: 0 seconds
phax commented 7 years ago

This is a Java 8 topic. You need to pass the system property javax.xml.accessExternalDTD=all before calling it. See https://docs.oracle.com/javase/tutorial/jaxp/properties/properties.html for details. I think there is an existing task to do that??

A solution for Ant may be to use ANT_OPTS environment variable as shown in http://stackoverflow.com/questions/21147974/set-a-system-property-with-ant

stefan-jung commented 7 years ago

Tested this on Windows and it works. đŸ„‡ 😃

Thank you so much, this is a very important feature!