1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.helger.schematron.pure;
18
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertNotNull;
22 import static org.junit.Assert.assertTrue;
23
24 import java.nio.charset.StandardCharsets;
25 import java.util.List;
26
27 import javax.xml.validation.Schema;
28
29 import org.junit.Test;
30 import org.oclc.purl.dsdl.svrl.SchematronOutputType;
31 import org.w3c.dom.Document;
32 import org.w3c.dom.Node;
33 import org.xml.sax.SAXException;
34
35 import com.helger.commons.io.resource.ClassPathResource;
36 import com.helger.commons.io.resource.IReadableResource;
37 import com.helger.commons.io.stream.StringInputStream;
38 import com.helger.schematron.SchematronException;
39 import com.helger.schematron.pure.errorhandler.CollectingPSErrorHandler;
40 import com.helger.schematron.pure.errorhandler.DoNothingPSErrorHandler;
41 import com.helger.schematron.pure.errorhandler.LoggingPSErrorHandler;
42 import com.helger.schematron.svrl.SVRLHelper;
43 import com.helger.schematron.testfiles.SchematronTestHelper;
44 import com.helger.schematron.xpath.XQueryAsXPathFunctionConverter;
45 import com.helger.xml.schema.XMLSchemaCache;
46 import com.helger.xml.serialize.read.DOMReader;
47 import com.helger.xml.serialize.read.DOMReaderSettings;
48 import com.helger.xml.xpath.MapBasedXPathFunctionResolver;
49 import com.helger.xml.xpath.MapBasedXPathVariableResolver;
50
51
52
53
54
55
56 public final class SchematronResourcePureTest
57 {
58 @Test
59 public void testBasic () throws Exception
60 {
61 for (final IReadableResource aRes : SchematronTestHelper.getAllValidSchematronFiles ())
62 {
63
64
65 final SchematronResourcePure aResPure = new SchematronResourcePure (aRes);
66 assertTrue (aRes.getPath (), aResPure.isValidSchematron ());
67 }
68 }
69
70 @Test
71 public void testFromByteArray ()
72 {
73 final String sTest = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" +
74 "<iso:schema xmlns=\"http://purl.oclc.org/dsdl/schematron\" \n" +
75 " xmlns:iso=\"http://purl.oclc.org/dsdl/schematron\" \n" +
76 " xmlns:sch=\"http://www.ascc.net/xml/schematron\"\n" +
77 " queryBinding='xslt2'\n" +
78 " schemaVersion=\"ISO19757-3\">\n" +
79 " <iso:title>Test ISO schematron file. Introduction mode</iso:title>\n" +
80 " <iso:ns prefix=\"dp\" uri=\"http://www.dpawson.co.uk/ns#\" />\n" +
81 " <iso:pattern >\n" +
82 " <iso:title>A very simple pattern with a title</iso:title>\n" +
83 " <iso:rule context=\"chapter\">\n" +
84 " <iso:assert test=\"title\">Chapter should have a title</iso:assert>\n" +
85 " <iso:report test=\"count(para)\">\n" +
86 " <iso:value-of select=\"count(para)\"/> paragraphs</iso:report>\n" +
87 " </iso:rule>\n" +
88 " </iso:pattern>\n" +
89 "\n" +
90 "</iso:schema>";
91 assertTrue (SchematronResourcePure.fromByteArray (sTest.getBytes (StandardCharsets.UTF_8)).isValidSchematron ());
92 assertTrue (SchematronResourcePure.fromInputStream (new StringInputStream (sTest, StandardCharsets.UTF_8))
93 .isValidSchematron ());
94 }
95
96 @Test
97 public void testParseWithXPathError ()
98 {
99 final String sTest = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" +
100 "<iso:schema xmlns=\"http://purl.oclc.org/dsdl/schematron\" \n" +
101 " xmlns:iso=\"http://purl.oclc.org/dsdl/schematron\" \n" +
102 " xmlns:sch=\"http://www.ascc.net/xml/schematron\"\n" +
103 " queryBinding='xslt2'\n" +
104 " schemaVersion=\"ISO19757-3\">\n" +
105 " <iso:title>Test ISO schematron file. Introduction mode</iso:title>\n" +
106 " <iso:ns prefix=\"dp\" uri=\"http://www.dpawson.co.uk/ns#\" />\n" +
107 " <iso:pattern>\n" +
108 " <iso:rule context=\"chapter\">\n"
109
110
111 + " <iso:assert test=\"title xor 55\">Chapter should have a title</iso:assert>\n"
112
113
114 +
115 " <iso:assert test=\"title xor 33\">Chapter should have a title</iso:assert>\n" +
116 " </iso:rule>\n" + " </iso:pattern>\n" + "</iso:schema>";
117 final CollectingPSErrorHandler aErrorHandler = new CollectingPSErrorHandler ();
118 final SchematronResourcePure aSch = SchematronResourcePure.fromByteArray (sTest.getBytes (StandardCharsets.UTF_8))
119 .setErrorHandler (aErrorHandler);
120
121 assertFalse (aSch.isValidSchematron ());
122 assertEquals ("Expected three errors: " +
123 aErrorHandler.getErrorList ().toString (),
124 3,
125 aErrorHandler.getErrorList ().getSize ());
126 if (false)
127 System.out.println (aErrorHandler.getErrorList ().toString ());
128
129
130 aErrorHandler.clearResourceErrors ();
131 aSch.validateCompletely ();
132 assertEquals ("Expected three errors: " +
133 aErrorHandler.getErrorList ().toString (),
134 3,
135 aErrorHandler.getErrorList ().getSize ());
136 }
137
138 @Test
139 public void testResolveVariables () throws SchematronException, SAXException
140 {
141 final String sTest = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" +
142 "<iso:schema xmlns=\"http://purl.oclc.org/dsdl/schematron\" \n" +
143 " xmlns:iso=\"http://purl.oclc.org/dsdl/schematron\" \n" +
144 " xmlns:sch=\"http://www.ascc.net/xml/schematron\"\n" +
145 " queryBinding='xslt2'\n" +
146 " schemaVersion=\"ISO19757-3\">\n" +
147 " <iso:title>Test ISO schematron file. Introduction mode</iso:title>\n" +
148 " <iso:ns prefix=\"dp\" uri=\"http://www.dpawson.co.uk/ns#\" />\n" +
149 " <iso:ns prefix=\"java\" uri=\"http://helger.com/schematron/test\" />\n" +
150 " <iso:pattern >\n" +
151 " <iso:title>A very simple pattern with a title</iso:title>\n" +
152 " <iso:rule context=\"chapter\">\n"
153
154 + " <iso:assert test=\"$title-element\">Chapter should have a title</iso:assert>\n"
155
156 + " <iso:report test=\"java:my-count(para) = 2\">\n"
157
158 +
159 " <iso:value-of select=\"java:my-count(para)\"/> paragraphs found</iso:report>\n" +
160 " </iso:rule>\n" + " </iso:pattern>\n" + "\n" + "</iso:schema>";
161
162
163
164 assertFalse (SchematronResourcePure.fromString (sTest, StandardCharsets.UTF_8)
165 .setErrorHandler (new DoNothingPSErrorHandler ())
166 .isValidSchematron ());
167
168
169 final MapBasedXPathVariableResolver aVarResolver = new MapBasedXPathVariableResolver ();
170 aVarResolver.addUniqueVariable ("title-element", "title");
171
172 final MapBasedXPathFunctionResolver aFunctionResolver = new MapBasedXPathFunctionResolver ();
173 aFunctionResolver.addUniqueFunction ("http://helger.com/schematron/test", "my-count", 1, args -> {
174 final List <?> aArg = (List <?>) args.get (0);
175 return Integer.valueOf (aArg.size ());
176 });
177 final Document aTestDoc = DOMReader.readXMLDOM ("<?xml version='1.0'?><chapter><title /><para>First para</para><para>Second para</para></chapter>");
178 final SchematronOutputType aOT = SchematronResourcePure.fromString (sTest, StandardCharsets.UTF_8)
179 .setVariableResolver (aVarResolver)
180 .setFunctionResolver (aFunctionResolver)
181 .applySchematronValidationToSVRL (aTestDoc);
182 assertNotNull (aOT);
183 assertEquals (0, SVRLHelper.getAllFailedAssertions (aOT).size ());
184 assertEquals (1, SVRLHelper.getAllSuccessfulReports (aOT).size ());
185
186 assertEquals ("\n 2 paragraphs found", SVRLHelper.getAllSuccessfulReports (aOT).get (0).getText ());
187 }
188
189 @Test
190 public void testResolveFunctions () throws SchematronException, SAXException
191 {
192 final String sTest = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" +
193 "<iso:schema xmlns=\"http://purl.oclc.org/dsdl/schematron\" \n" +
194 " xmlns:iso=\"http://purl.oclc.org/dsdl/schematron\" \n" +
195 " xmlns:sch=\"http://www.ascc.net/xml/schematron\"\n" +
196 " queryBinding='xslt2'\n" +
197 " schemaVersion=\"ISO19757-3\">\n" +
198 " <iso:title>Test ISO schematron file. Introduction mode</iso:title>\n" +
199 " <iso:ns prefix=\"dp\" uri=\"http://www.dpawson.co.uk/ns#\" />\n" +
200 " <iso:ns prefix=\"java\" uri=\"http://helger.com/schematron/test\" />\n" +
201 " <iso:pattern >\n" +
202 " <iso:title>A very simple pattern with a title</iso:title>\n" +
203 " <iso:rule context=\"chapter\">\n" +
204 " <iso:assert test=\"title\">Chapter should have a title</iso:assert>\n" +
205 " <iso:report test=\"count(para) = 2\">\n"
206
207 +
208 " Node details: <iso:value-of select=\"java:get-nodelist-details(para)\"/> - end</iso:report>\n" +
209 " </iso:rule>\n" + " </iso:pattern>\n" + "\n" + "</iso:schema>";
210
211
212 final MapBasedXPathFunctionResolver aFunctionResolver = new MapBasedXPathFunctionResolver ();
213 aFunctionResolver.addUniqueFunction ("http://helger.com/schematron/test", "get-nodelist-details", 1, args -> {
214
215 assertEquals (1, args.size ());
216
217
218 final List <?> aFirstArg = (List <?>) args.get (0);
219
220
221 final StringBuilder ret = new StringBuilder ();
222 boolean bFirst = true;
223 for (final Object aFirstArgItem : aFirstArg)
224 {
225 assertTrue (aFirstArgItem instanceof Node);
226 final Node aNode = (Node) aFirstArgItem;
227
228 if (bFirst)
229 bFirst = false;
230 else
231 ret.append (", ");
232
233 ret.append (aNode.getNodeName ()).append ("[").append (aNode.getTextContent ()).append ("]");
234 }
235
236 return ret;
237 });
238
239 final Document aTestDoc = DOMReader.readXMLDOM ("<?xml version='1.0'?>" +
240 "<chapter>" +
241 "<title />" +
242 "<para>First para</para>" +
243 "<para>Second para</para>" +
244 "</chapter>");
245 final SchematronOutputType aOT = SchematronResourcePure.fromString (sTest, StandardCharsets.UTF_8)
246 .setFunctionResolver (aFunctionResolver)
247 .applySchematronValidationToSVRL (aTestDoc);
248 assertNotNull (aOT);
249 assertEquals (0, SVRLHelper.getAllFailedAssertions (aOT).size ());
250 assertEquals (1, SVRLHelper.getAllSuccessfulReports (aOT).size ());
251
252 assertEquals ("\n Node details: para[First para], para[Second para] - end",
253 SVRLHelper.getAllSuccessfulReports (aOT).get (0).getText ());
254 }
255
256 @Test
257 public void testResolveXQueryFunctions () throws Exception
258 {
259 final String sTest = "<?xml version='1.0' encoding='iso-8859-1'?>\n" +
260 "<iso:schema xmlns='http://purl.oclc.org/dsdl/schematron' \n" +
261 " xmlns:iso='http://purl.oclc.org/dsdl/schematron' \n" +
262 " xmlns:sch='http://www.ascc.net/xml/schematron'\n" +
263 " queryBinding='xslt2'\n" +
264 " schemaVersion='ISO19757-3'>\n" +
265 " <iso:title>Test ISO schematron file. Introduction mode</iso:title>\n" +
266 " <iso:ns prefix='dp' uri='http://www.dpawson.co.uk/ns#' />\n" +
267 " <iso:ns prefix='functx' uri='http://www.functx.com' />\n" +
268 " <iso:pattern >\n" +
269 " <iso:title>A very simple pattern with a title</iso:title>\n" +
270 " <iso:rule context='chapter'>\n" +
271 " <iso:assert test='title'>Chapter should have a title</iso:assert>\n" +
272 " <iso:report test='count(para) = 2'>\n"
273
274 +
275 " Node kind: <iso:value-of select='functx:node-kind(para)'/> - end</iso:report>\n" +
276 " </iso:rule>\n" + " </iso:pattern>\n" + "\n" + "</iso:schema>";
277
278 final MapBasedXPathFunctionResolver aFunctionResolver = new XQueryAsXPathFunctionConverter ().loadXQuery (ClassPathResource.getInputStream ("xquery/functx-1.0-nodoc-2007-01.xq"));
279
280
281 final Document aTestDoc = DOMReader.readXMLDOM ("<?xml version='1.0'?>" +
282 "<chapter>" +
283 "<title />" +
284 "<para>First para</para>" +
285 "<para>Second para</para>" +
286 "</chapter>");
287 final SchematronOutputType aOT = SchematronResourcePure.fromString (sTest, StandardCharsets.UTF_8)
288 .setFunctionResolver (aFunctionResolver)
289 .applySchematronValidationToSVRL (aTestDoc);
290 assertNotNull (aOT);
291 assertEquals (0, SVRLHelper.getAllFailedAssertions (aOT).size ());
292 assertEquals (1, SVRLHelper.getAllSuccessfulReports (aOT).size ());
293
294 assertEquals ("\n Node kind: element - end", SVRLHelper.getAllSuccessfulReports (aOT).get (0).getText ());
295 }
296
297 @Test
298 public void testResolveFunctXAreDistinctValuesQueryFunctions () throws Exception
299 {
300 final String sTest = "<?xml version='1.0' encoding='iso-8859-1'?>\n" +
301 "<iso:schema xmlns='http://purl.oclc.org/dsdl/schematron' \n" +
302 " xmlns:iso='http://purl.oclc.org/dsdl/schematron' \n" +
303 " xmlns:sch='http://www.ascc.net/xml/schematron'\n" +
304 " queryBinding='xslt2'\n" +
305 " schemaVersion='ISO19757-3'>\n" +
306 " <iso:title>Test ISO schematron file. Introduction mode</iso:title>\n" +
307 " <iso:ns prefix='dp' uri='http://www.dpawson.co.uk/ns#' />\n" +
308 " <iso:ns prefix='fn' uri='http://www.w3.org/2005/xpath-functions' />\n" +
309 " <iso:ns prefix='functx' uri='http://www.functx.com' />\n" +
310 " <iso:pattern >\n" +
311 " <iso:title>A very simple pattern with a title</iso:title>\n" +
312 " <iso:rule context='chapter'>\n" +
313 " <iso:assert test='functx:are-distinct-values(para)'>Should have distinct values</iso:assert>\n" +
314 " </iso:rule>\n" +
315 " </iso:pattern>\n" +
316 "</iso:schema>";
317
318 final MapBasedXPathFunctionResolver aFunctionResolver = new XQueryAsXPathFunctionConverter ().loadXQuery (ClassPathResource.getInputStream ("xquery/functx-1.0-nodoc-2007-01.xq"));
319
320
321 final Document aTestDoc = DOMReader.readXMLDOM ("<?xml version='1.0'?>" +
322 "<chapter>" +
323 "<title />" +
324 "<para>100</para>" +
325 "<para>200</para>" +
326 "</chapter>");
327 final CollectingPSErrorHandler aErrorHandler = new CollectingPSErrorHandler (new LoggingPSErrorHandler ());
328 final SchematronOutputType aOT = SchematronResourcePure.fromString (sTest, StandardCharsets.UTF_8)
329 .setFunctionResolver (aFunctionResolver)
330 .setErrorHandler (aErrorHandler)
331 .applySchematronValidationToSVRL (aTestDoc);
332 assertNotNull (aOT);
333
334 if (false)
335 assertTrue (aErrorHandler.getAllErrors ().toString (), aErrorHandler.isEmpty ());
336 assertEquals (0, SVRLHelper.getAllFailedAssertions (aOT).size ());
337 }
338
339 @Test
340 public void testFunctXAreDistinctValuesWithXSD () throws Exception
341 {
342 final String sTest = "<?xml version='1.0' encoding='iso-8859-1'?>\n" +
343 "<schema xmlns='http://purl.oclc.org/dsdl/schematron'>\n" +
344 " <ns prefix=\"xs\" uri=\"http://www.w3.org/2001/XMLSchema\"/>\n" +
345 " <ns prefix='fn' uri='http://www.w3.org/2005/xpath-functions' />\n" +
346 " <ns prefix='functx' uri='http://www.functx.com' />\n" +
347 " <pattern name='toto'>\n" +
348 " <title>A very simple pattern with a title</title>\n" +
349 " <rule context='chapter'>\n" +
350 " <assert test='fn:count(fn:distinct-values(para)) = fn:count(para)'>Should have distinct values</assert>\n" +
351 " </rule>\n" +
352 " </pattern>\n" +
353 "</schema>";
354
355 final MapBasedXPathFunctionResolver aFunctionResolver = new XQueryAsXPathFunctionConverter ().loadXQuery (ClassPathResource.getInputStream ("xquery/functx-1.0-nodoc-2007-01.xq"));
356
357 final Schema aSchema = XMLSchemaCache.getInstance ()
358 .getSchema (new ClassPathResource ("issues/20141124/chapter.xsd"));
359 final Document aTestDoc = DOMReader.readXMLDOM ("<?xml version='1.0'?>" +
360 "<chapter>" +
361 " <title />" +
362 " <para>09</para>" +
363 " <para>9</para>" +
364 "</chapter>",
365 new DOMReaderSettings ().setSchema (aSchema));
366
367 final SchematronOutputType aOT = SchematronResourcePure.fromString (sTest, StandardCharsets.UTF_8)
368 .setFunctionResolver (aFunctionResolver)
369 .applySchematronValidationToSVRL (aTestDoc);
370 assertNotNull (aOT);
371 if (SVRLHelper.getAllFailedAssertions (aOT).size () != 0)
372 {
373 System.out.println (SVRLHelper.getAllFailedAssertions (aOT).get (0).getText ());
374 }
375 assertTrue (SVRLHelper.getAllFailedAssertions (aOT).isEmpty ());
376 }
377 }