1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.helger.schematron.pure.exchange;
18
19 import javax.annotation.Nonnull;
20 import javax.annotation.Nullable;
21 import javax.annotation.concurrent.Immutable;
22
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25 import org.xml.sax.EntityResolver;
26
27 import com.helger.commons.ValueEnforcer;
28 import com.helger.commons.io.resource.IReadableResource;
29 import com.helger.commons.string.StringParser;
30 import com.helger.commons.string.ToStringGenerator;
31 import com.helger.schematron.CSchematron;
32 import com.helger.schematron.CSchematronXML;
33 import com.helger.schematron.SchematronDebug;
34 import com.helger.schematron.SchematronHelper;
35 import com.helger.schematron.pure.errorhandler.IPSErrorHandler;
36 import com.helger.schematron.pure.errorhandler.LoggingPSErrorHandler;
37 import com.helger.schematron.pure.model.*;
38 import com.helger.schematron.pure.model.PSDir.EDirValue;
39 import com.helger.schematron.pure.model.PSRichGroup.ESpace;
40 import com.helger.xml.microdom.IMicroDocument;
41 import com.helger.xml.microdom.IMicroElement;
42 import com.helger.xml.microdom.IMicroText;
43 import com.helger.xml.microdom.serialize.MicroWriter;
44 import com.helger.xml.serialize.read.SAXReaderSettings;
45
46
47
48
49
50
51 @Immutable
52 public class PSReader
53 {
54 private static final Logger s_aLogger = LoggerFactory.getLogger (PSReader.class);
55
56 private final IReadableResource m_aResource;
57 private final IPSErrorHandler m_aErrorHandler;
58 private final EntityResolver m_aEntityResolver;
59
60
61
62
63
64
65
66
67 public PSReader (@Nonnull final IReadableResource aResource)
68 {
69 this (aResource, null, null);
70 }
71
72
73
74
75
76
77
78
79
80
81
82
83 public PSReader (@Nonnull final IReadableResource aResource, @Nullable final IPSErrorHandler aErrorHandler)
84 {
85 this (aResource, aErrorHandler, null);
86 }
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102 public PSReader (@Nonnull final IReadableResource aResource,
103 @Nullable final IPSErrorHandler aErrorHandler,
104 @Nullable final EntityResolver aEntityResolver)
105 {
106 ValueEnforcer.notNull (aResource, "Resource");
107 m_aResource = aResource;
108 m_aErrorHandler = aErrorHandler != null ? aErrorHandler : new LoggingPSErrorHandler ();
109 m_aEntityResolver = aEntityResolver;
110 }
111
112
113
114
115
116 @Nonnull
117 public IReadableResource getResource ()
118 {
119 return m_aResource;
120 }
121
122
123
124
125
126
127 @Nonnull
128 public IPSErrorHandler getErrorHandler ()
129 {
130 return m_aErrorHandler;
131 }
132
133
134
135
136
137
138
139
140
141 @Nullable
142 private static String _getAttributeValue (@Nullable final String sAttrValue)
143 {
144 return sAttrValue == null ? null : sAttrValue.trim ();
145 }
146
147
148
149
150
151
152
153
154
155 private void _warn (@Nonnull final IPSElement aSourceElement, @Nonnull final String sMessage)
156 {
157 ValueEnforcer.notNull (aSourceElement, "SourceElement");
158 ValueEnforcer.notNull (sMessage, "Message");
159
160 m_aErrorHandler.warn (m_aResource, aSourceElement, sMessage);
161 }
162
163
164
165
166
167
168
169
170 @Nonnull
171 public PSActive readActiveFromXML (@Nonnull final IMicroElement eActive)
172 {
173 final PSActive ret = new PSActive ();
174 eActive.forAllAttributes ( (sNS, sAttrName, sVal) -> {
175 final String sAttrValue = _getAttributeValue (sVal);
176 if (sAttrName.equals (CSchematronXML.ATTR_PATTERN))
177 ret.setPattern (sAttrValue);
178 else
179 ret.addForeignAttribute (sAttrName, sAttrValue);
180 });
181
182 eActive.forAllChildren (aActiveChild -> {
183 switch (aActiveChild.getType ())
184 {
185 case TEXT:
186 ret.addText (((IMicroText) aActiveChild).getNodeValue ());
187 break;
188 case ELEMENT:
189 final IMicroElement eElement = (IMicroElement) aActiveChild;
190 if (CSchematron.NAMESPACE_SCHEMATRON.equals (eElement.getNamespaceURI ()))
191 {
192 final String sLocalName = eElement.getLocalName ();
193 if (sLocalName.equals (CSchematronXML.ELEMENT_DIR))
194 ret.addDir (readDirFromXML (eElement));
195 else
196 if (sLocalName.equals (CSchematronXML.ELEMENT_EMPH))
197 ret.addEmph (readEmphFromXML (eElement));
198 else
199 if (sLocalName.equals (CSchematronXML.ELEMENT_SPAN))
200 ret.addSpan (readSpanFromXML (eElement));
201 else
202 _warn (ret, "Unsupported Schematron element '" + sLocalName + "'");
203 }
204 else
205 ret.addForeignElement (eElement.getClone ());
206
207 break;
208 case COMMENT:
209
210 break;
211 default:
212 _warn (ret, "Unsupported child node: " + aActiveChild);
213 }
214 });
215 return ret;
216 }
217
218 private void _handleRichGroup (@Nonnull final String sAttrName,
219 @Nonnull final String sAttrValue,
220 @Nonnull final PSRichGroup aRichGroup)
221 {
222 if (sAttrName.equals (CSchematronXML.ATTR_ICON))
223 aRichGroup.setIcon (sAttrValue);
224 else
225 if (sAttrName.equals (CSchematronXML.ATTR_SEE))
226 aRichGroup.setSee (sAttrValue);
227 else
228 if (sAttrName.equals (CSchematronXML.ATTR_FPI))
229 aRichGroup.setFPI (sAttrValue);
230 else
231 if (sAttrName.equals (CSchematronXML.ATTR_XML_LANG))
232 aRichGroup.setXmlLang (sAttrValue);
233 else
234 if (sAttrName.equals (CSchematronXML.ATTR_XML_SPACE))
235 aRichGroup.setXmlSpace (ESpace.getFromIDOrNull (sAttrValue));
236 }
237
238 private void _handleLinkableGroup (@Nonnull final String sAttrName,
239 @Nonnull final String sAttrValue,
240 @Nonnull final PSLinkableGroup aLinkableGroup)
241 {
242 if (sAttrName.equals (CSchematronXML.ATTR_ROLE))
243 aLinkableGroup.setRole (sAttrValue);
244 else
245 if (sAttrName.equals (CSchematronXML.ATTR_SUBJECT))
246 aLinkableGroup.setSubject (sAttrValue);
247 }
248
249
250
251
252
253
254
255
256 @Nonnull
257 public PSAssertReport readAssertReportFromXML (@Nonnull final IMicroElement eAssertReport)
258 {
259 final PSAssertReport ret = new PSAssertReport (eAssertReport.getLocalName ()
260 .equals (CSchematronXML.ELEMENT_ASSERT));
261
262 final PSRichGroup aRichGroup = new PSRichGroup ();
263 final PSLinkableGroup aLinkableGroup = new PSLinkableGroup ();
264 eAssertReport.forAllAttributes ( (sNS, sAttrName, sVal) -> {
265 final String sAttrValue = _getAttributeValue (sVal);
266 if (sAttrName.equals (CSchematronXML.ATTR_TEST))
267 ret.setTest (sAttrValue);
268 else
269 if (sAttrName.equals (CSchematronXML.ATTR_FLAG))
270 ret.setFlag (sAttrValue);
271 else
272 if (sAttrName.equals (CSchematronXML.ATTR_ID))
273 ret.setID (sAttrValue);
274 else
275 if (sAttrName.equals (CSchematronXML.ATTR_DIAGNOSTICS))
276 ret.setDiagnostics (sAttrValue);
277 else
278 if (PSRichGroup.isRichAttribute (sAttrName))
279 _handleRichGroup (sAttrName, sAttrValue, aRichGroup);
280 else
281 if (PSLinkableGroup.isLinkableAttribute (sAttrName))
282 _handleLinkableGroup (sAttrName, sAttrValue, aLinkableGroup);
283 else
284 ret.addForeignAttribute (sAttrName, sAttrValue);
285 });
286 ret.setRich (aRichGroup);
287 ret.setLinkable (aLinkableGroup);
288
289 eAssertReport.forAllChildren (aAssertReportChild -> {
290 switch (aAssertReportChild.getType ())
291 {
292 case TEXT:
293 ret.addText (((IMicroText) aAssertReportChild).getNodeValue ());
294 break;
295 case ELEMENT:
296 final IMicroElement eElement = (IMicroElement) aAssertReportChild;
297 if (CSchematron.NAMESPACE_SCHEMATRON.equals (eElement.getNamespaceURI ()))
298 {
299 final String sLocalName = eElement.getLocalName ();
300 if (sLocalName.equals (CSchematronXML.ELEMENT_NAME))
301 ret.addName (readNameFromXML (eElement));
302 else
303 if (sLocalName.equals (CSchematronXML.ELEMENT_VALUE_OF))
304 ret.addValueOf (readValueOfFromXML (eElement));
305 else
306 if (sLocalName.equals (CSchematronXML.ELEMENT_EMPH))
307 ret.addEmph (readEmphFromXML (eElement));
308 else
309 if (sLocalName.equals (CSchematronXML.ELEMENT_DIR))
310 ret.addDir (readDirFromXML (eElement));
311 else
312 if (sLocalName.equals (CSchematronXML.ELEMENT_SPAN))
313 ret.addSpan (readSpanFromXML (eElement));
314 else
315 _warn (ret, "Unsupported Schematron element '" + sLocalName + "'");
316 }
317 else
318 ret.addForeignElement (eElement.getClone ());
319
320 break;
321 case COMMENT:
322
323 break;
324 default:
325 _warn (ret, "Unsupported child node: " + aAssertReportChild);
326 }
327 });
328 return ret;
329 }
330
331
332
333
334
335
336
337
338 @Nonnull
339 public PSDiagnostic readDiagnosticFromXML (@Nonnull final IMicroElement eDiagnostic)
340 {
341 final PSDiagnostic ret = new PSDiagnostic ();
342
343 final PSRichGroup aRichGroup = new PSRichGroup ();
344 eDiagnostic.forAllAttributes ( (sNS, sAttrName, sVal) -> {
345 final String sAttrValue = _getAttributeValue (sVal);
346 if (sAttrName.equals (CSchematronXML.ATTR_ID))
347 ret.setID (sAttrValue);
348 else
349 if (PSRichGroup.isRichAttribute (sAttrName))
350 _handleRichGroup (sAttrName, sAttrValue, aRichGroup);
351 else
352 ret.addForeignAttribute (sAttrName, sAttrValue);
353 });
354 ret.setRich (aRichGroup);
355
356 eDiagnostic.forAllChildren (aDiagnosticChild -> {
357 switch (aDiagnosticChild.getType ())
358 {
359 case TEXT:
360 ret.addText (((IMicroText) aDiagnosticChild).getNodeValue ());
361 break;
362 case ELEMENT:
363 final IMicroElement eElement = (IMicroElement) aDiagnosticChild;
364 if (CSchematron.NAMESPACE_SCHEMATRON.equals (eElement.getNamespaceURI ()))
365 {
366 final String sLocalName = eElement.getLocalName ();
367 if (sLocalName.equals (CSchematronXML.ELEMENT_VALUE_OF))
368 ret.addValueOf (readValueOfFromXML (eElement));
369 else
370 if (sLocalName.equals (CSchematronXML.ELEMENT_EMPH))
371 ret.addEmph (readEmphFromXML (eElement));
372 else
373 if (sLocalName.equals (CSchematronXML.ELEMENT_DIR))
374 ret.addDir (readDirFromXML (eElement));
375 else
376 if (sLocalName.equals (CSchematronXML.ELEMENT_SPAN))
377 ret.addSpan (readSpanFromXML (eElement));
378 else
379 _warn (ret, "Unsupported Schematron element '" + sLocalName + "'");
380 }
381 else
382 ret.addForeignElement (eElement.getClone ());
383
384 break;
385 case COMMENT:
386
387 break;
388 default:
389 _warn (ret, "Unsupported child node: " + aDiagnosticChild);
390 }
391 });
392 return ret;
393 }
394
395
396
397
398
399
400
401
402 @Nonnull
403 public PSDiagnostics readDiagnosticsFromXML (@Nonnull final IMicroElement eDiagnostics)
404 {
405 final PSDiagnostics ret = new PSDiagnostics ();
406
407 eDiagnostics.forAllAttributes ( (sNS, sAttrName, sVal) -> {
408 final String sAttrValue = _getAttributeValue (sVal);
409 ret.addForeignAttribute (sAttrName, sAttrValue);
410 });
411
412 eDiagnostics.forAllChildElements (eDiagnosticsChild -> {
413 if (CSchematron.NAMESPACE_SCHEMATRON.equals (eDiagnosticsChild.getNamespaceURI ()))
414 {
415 if (eDiagnosticsChild.getLocalName ().equals (CSchematronXML.ELEMENT_INCLUDE))
416 ret.addInclude (readIncludeFromXML (eDiagnosticsChild));
417 else
418 if (eDiagnosticsChild.getLocalName ().equals (CSchematronXML.ELEMENT_DIAGNOSTIC))
419 ret.addDiagnostic (readDiagnosticFromXML (eDiagnosticsChild));
420 else
421 _warn (ret, "Unsupported Schematron element '" + eDiagnosticsChild.getLocalName () + "'");
422 }
423 else
424 ret.addForeignElement (eDiagnosticsChild.getClone ());
425 });
426 return ret;
427 }
428
429
430
431
432
433
434
435
436 @Nonnull
437 public PSDir readDirFromXML (@Nonnull final IMicroElement eDir)
438 {
439 final PSDir ret = new PSDir ();
440
441 eDir.forAllAttributes ( (sNS, sAttrName, sVal) -> {
442 final String sAttrValue = _getAttributeValue (sVal);
443 if (sAttrName.equals (CSchematronXML.ATTR_VALUE))
444 ret.setValue (EDirValue.getFromIDOrNull (sAttrValue));
445 else
446 ret.addForeignAttribute (sAttrName, sAttrValue);
447 });
448
449 eDir.forAllChildren (aDirChild -> {
450 switch (aDirChild.getType ())
451 {
452 case TEXT:
453 ret.addText (((IMicroText) aDirChild).getNodeValue ());
454 break;
455 case ELEMENT:
456 final IMicroElement eElement = (IMicroElement) aDirChild;
457 if (CSchematron.NAMESPACE_SCHEMATRON.equals (eElement.getNamespaceURI ()))
458 {
459 _warn (ret, "Unsupported Schematron element '" + eElement.getLocalName () + "'");
460 }
461 else
462 ret.addForeignElement (eElement.getClone ());
463
464 break;
465 case COMMENT:
466
467 break;
468 default:
469 _warn (ret, "Unsupported child node: " + aDirChild);
470 }
471 });
472 return ret;
473 }
474
475
476
477
478
479
480
481
482 @Nonnull
483 public PSEmph readEmphFromXML (@Nonnull final IMicroElement eEmph)
484 {
485 final PSEmph ret = new PSEmph ();
486
487 eEmph.forAllAttributes ( (sNS, sAttrName, sVal) -> {
488 final String sAttrValue = _getAttributeValue (sVal);
489 _warn (ret, "Unsupported attribute '" + sAttrName + "'='" + sAttrValue + "'");
490 });
491
492 eEmph.forAllChildren (aEmphChild -> {
493 switch (aEmphChild.getType ())
494 {
495 case TEXT:
496 ret.addText (((IMicroText) aEmphChild).getNodeValue ());
497 break;
498 case ELEMENT:
499 final IMicroElement eElement = (IMicroElement) aEmphChild;
500 if (CSchematron.NAMESPACE_SCHEMATRON.equals (eElement.getNamespaceURI ()))
501 {
502 _warn (ret, "Unsupported Schematron element '" + eElement.getLocalName () + "'");
503 }
504 else
505 _warn (ret, "Unsupported namespace URI '" + eElement.getNamespaceURI () + "'");
506
507 break;
508 case COMMENT:
509
510 break;
511 default:
512 _warn (ret, "Unsupported child node: " + aEmphChild);
513 }
514 });
515 return ret;
516 }
517
518
519
520
521
522
523
524
525 @Nonnull
526 public PSExtends readExtendsFromXML (@Nonnull final IMicroElement eExtends)
527 {
528 final PSExtends ret = new PSExtends ();
529
530 eExtends.forAllAttributes ( (sNS, sAttrName, sVal) -> {
531 final String sAttrValue = _getAttributeValue (sVal);
532 if (sAttrName.equals (CSchematronXML.ATTR_RULE))
533 ret.setRule (sAttrValue);
534 else
535 ret.addForeignAttribute (sAttrName, sAttrValue);
536 });
537
538 eExtends.forAllChildElements (eChild -> {
539 if (CSchematron.NAMESPACE_SCHEMATRON.equals (eChild.getNamespaceURI ()))
540 {
541 _warn (ret, "Unsupported Schematron element '" + eChild.getLocalName () + "'");
542 }
543 else
544 _warn (ret, "Unsupported namespace URI '" + eChild.getNamespaceURI () + "'");
545 });
546 return ret;
547 }
548
549
550
551
552
553
554
555
556 @Nonnull
557 public PSInclude readIncludeFromXML (@Nonnull final IMicroElement eInclude)
558 {
559 final PSInclude ret = new PSInclude ();
560
561 eInclude.forAllAttributes ( (sNS, sAttrName, sVal) -> {
562 final String sAttrValue = _getAttributeValue (sVal);
563 if (sAttrName.equals (CSchematronXML.ATTR_HREF))
564 ret.setHref (sAttrValue);
565 else
566 _warn (ret, "Unsupported attribute '" + sAttrName + "'='" + sAttrValue + "'");
567 });
568
569 eInclude.forAllChildElements (eValueOfChild -> {
570 if (CSchematron.NAMESPACE_SCHEMATRON.equals (eValueOfChild.getNamespaceURI ()))
571 {
572 _warn (ret, "Unsupported Schematron element '" + eValueOfChild.getLocalName () + "'");
573 }
574 else
575 _warn (ret, "Unsupported namespace URI '" + eValueOfChild.getNamespaceURI () + "'");
576 });
577 return ret;
578 }
579
580
581
582
583
584
585
586
587 @Nonnull
588 public PSLet readLetFromXML (@Nonnull final IMicroElement eLet)
589 {
590 final PSLet ret = new PSLet ();
591
592 eLet.forAllAttributes ( (sNS, sAttrName, sVal) -> {
593 final String sAttrValue = _getAttributeValue (sVal);
594 if (sAttrName.equals (CSchematronXML.ATTR_NAME))
595 ret.setName (sAttrValue);
596 else
597 if (sAttrName.equals (CSchematronXML.ATTR_VALUE))
598 ret.setValue (sAttrValue);
599 else
600 _warn (ret, "Unsupported attribute '" + sAttrName + "'='" + sAttrValue + "'");
601 });
602
603 eLet.forAllChildElements (eLetChild -> {
604 if (CSchematron.NAMESPACE_SCHEMATRON.equals (eLetChild.getNamespaceURI ()))
605 {
606 _warn (ret, "Unsupported Schematron element '" + eLetChild.getLocalName () + "'");
607 }
608 else
609 _warn (ret, "Unsupported namespace URI '" + eLetChild.getNamespaceURI () + "'");
610 });
611 return ret;
612 }
613
614
615
616
617
618
619
620
621 @Nonnull
622 public PSName readNameFromXML (@Nonnull final IMicroElement eName)
623 {
624 final PSName ret = new PSName ();
625
626 eName.forAllAttributes ( (sNS, sAttrName, sVal) -> {
627 final String sAttrValue = _getAttributeValue (sVal);
628 if (sAttrName.equals (CSchematronXML.ATTR_PATH))
629 ret.setPath (sAttrValue);
630 else
631 ret.addForeignAttribute (sAttrName, sAttrValue);
632 });
633
634 eName.forAllChildElements (eNameChild -> {
635 if (CSchematron.NAMESPACE_SCHEMATRON.equals (eNameChild.getNamespaceURI ()))
636 {
637 _warn (ret, "Unsupported Schematron element '" + eNameChild.getLocalName () + "'");
638 }
639 else
640 _warn (ret, "Unsupported namespace URI '" + eNameChild.getNamespaceURI () + "'");
641 });
642 return ret;
643 }
644
645
646
647
648
649
650
651
652 @Nonnull
653 public PSNS readNSFromXML (@Nonnull final IMicroElement eNS)
654 {
655 final PSNS ret = new PSNS ();
656
657 eNS.forAllAttributes ( (sNS, sAttrName, sVal) -> {
658 final String sAttrValue = _getAttributeValue (sVal);
659 if (sAttrName.equals (CSchematronXML.ATTR_URI))
660 ret.setUri (sAttrValue);
661 else
662 if (sAttrName.equals (CSchematronXML.ATTR_PREFIX))
663 ret.setPrefix (sAttrValue);
664 else
665 ret.addForeignAttribute (sAttrName, sAttrValue);
666 });
667
668 eNS.forAllChildElements (eLetChild -> {
669 if (CSchematron.NAMESPACE_SCHEMATRON.equals (eLetChild.getNamespaceURI ()))
670 {
671 _warn (ret, "Unsupported Schematron element '" + eLetChild.getLocalName () + "'");
672 }
673 else
674 _warn (ret, "Unsupported namespace URI '" + eLetChild.getNamespaceURI () + "'");
675 });
676 return ret;
677 }
678
679
680
681
682
683
684
685
686 @Nonnull
687 public PSP readPFromXML (@Nonnull final IMicroElement eP)
688 {
689 final PSP ret = new PSP ();
690 eP.forAllAttributes ( (sNS, sAttrName, sVal) -> {
691 final String sAttrValue = _getAttributeValue (sVal);
692 if (sAttrName.equals (CSchematronXML.ATTR_ID))
693 ret.setID (sAttrValue);
694 else
695 if (sAttrName.equals (CSchematronXML.ATTR_CLASS))
696 ret.setClazz (sAttrValue);
697 else
698 if (sAttrName.equals (CSchematronXML.ATTR_ICON))
699 ret.setIcon (sAttrValue);
700 else
701 ret.addForeignAttribute (sAttrName, sAttrValue);
702 });
703
704 eP.forAllChildren (aChild -> {
705 switch (aChild.getType ())
706 {
707 case TEXT:
708 ret.addText (((IMicroText) aChild).getNodeValue ());
709 break;
710 case ELEMENT:
711 final IMicroElement eElement = (IMicroElement) aChild;
712 if (CSchematron.NAMESPACE_SCHEMATRON.equals (eElement.getNamespaceURI ()))
713 {
714 final String sLocalName = eElement.getLocalName ();
715 if (sLocalName.equals (CSchematronXML.ELEMENT_DIR))
716 ret.addDir (readDirFromXML (eElement));
717 else
718 if (sLocalName.equals (CSchematronXML.ELEMENT_EMPH))
719 ret.addEmph (readEmphFromXML (eElement));
720 else
721 if (sLocalName.equals (CSchematronXML.ELEMENT_SPAN))
722 ret.addSpan (readSpanFromXML (eElement));
723 else
724 _warn (ret, "Unsupported Schematron element '" + sLocalName + "'");
725 }
726 else
727 ret.addForeignElement (eElement.getClone ());
728
729 break;
730 case COMMENT:
731
732 break;
733 default:
734 _warn (ret, "Unsupported child node: " + aChild);
735 }
736 });
737 return ret;
738 }
739
740
741
742
743
744
745
746
747 @Nonnull
748 public PSParam readParamFromXML (@Nonnull final IMicroElement eParam)
749 {
750 final PSParam ret = new PSParam ();
751
752 eParam.forAllAttributes ( (sNS, sAttrName, sVal) -> {
753 final String sAttrValue = _getAttributeValue (sVal);
754 if (sAttrName.equals (CSchematronXML.ATTR_NAME))
755 ret.setName (sAttrValue);
756 else
757 if (sAttrName.equals (CSchematronXML.ATTR_VALUE))
758 ret.setValue (sAttrValue);
759 else
760 _warn (ret, "Unsupported attribute '" + sAttrName + "'='" + sAttrValue + "'");
761 });
762
763 eParam.forAllChildElements (eParamChild -> {
764 if (CSchematron.NAMESPACE_SCHEMATRON.equals (eParamChild.getNamespaceURI ()))
765 {
766 _warn (ret, "Unsupported Schematron element '" + eParamChild.getLocalName () + "'");
767 }
768 else
769 _warn (ret, "Unsupported namespace URI '" + eParamChild.getNamespaceURI () + "'");
770 });
771 return ret;
772 }
773
774
775
776
777
778
779
780
781 @Nonnull
782 public PSPattern readPatternFromXML (@Nonnull final IMicroElement ePattern)
783 {
784 final PSPattern ret = new PSPattern ();
785
786 final PSRichGroup aRichGroup = new PSRichGroup ();
787 ePattern.forAllAttributes ( (sNS, sAttrName, sVal) -> {
788 final String sAttrValue = _getAttributeValue (sVal);
789 if (sAttrName.equals (CSchematronXML.ATTR_ABSTRACT))
790 ret.setAbstract (StringParser.parseBool (sAttrValue));
791 else
792 if (sAttrName.equals (CSchematronXML.ATTR_ID))
793 ret.setID (sAttrValue);
794 else
795 if (sAttrName.equals (CSchematronXML.ATTR_IS_A))
796 ret.setIsA (sAttrValue);
797 else
798 if (PSRichGroup.isRichAttribute (sAttrName))
799 _handleRichGroup (sAttrName, sAttrValue, aRichGroup);
800 else
801 ret.addForeignAttribute (sAttrName, sAttrValue);
802 });
803 ret.setRich (aRichGroup);
804
805 ePattern.forAllChildElements (ePatternChild -> {
806 if (CSchematron.NAMESPACE_SCHEMATRON.equals (ePatternChild.getNamespaceURI ()))
807 {
808 if (ePatternChild.getLocalName ().equals (CSchematronXML.ELEMENT_INCLUDE))
809 ret.addInclude (readIncludeFromXML (ePatternChild));
810 else
811 if (ePatternChild.getLocalName ().equals (CSchematronXML.ELEMENT_TITLE))
812 ret.setTitle (readTitleFromXML (ePatternChild));
813 else
814 if (ePatternChild.getLocalName ().equals (CSchematronXML.ELEMENT_P))
815 ret.addP (readPFromXML (ePatternChild));
816 else
817 if (ePatternChild.getLocalName ().equals (CSchematronXML.ELEMENT_LET))
818 ret.addLet (readLetFromXML (ePatternChild));
819 else
820 if (ePatternChild.getLocalName ().equals (CSchematronXML.ELEMENT_RULE))
821 ret.addRule (readRuleFromXML (ePatternChild));
822 else
823 if (ePatternChild.getLocalName ().equals (CSchematronXML.ELEMENT_PARAM))
824 ret.addParam (readParamFromXML (ePatternChild));
825 else
826 _warn (ret,
827 "Unsupported Schematron element '" +
828 ePatternChild.getLocalName () +
829 "' in " +
830 ret.toString ());
831 }
832 else
833 ret.addForeignElement (ePatternChild.getClone ());
834 });
835 return ret;
836 }
837
838
839
840
841
842
843
844
845 @Nonnull
846 public PSPhase readPhaseFromXML (@Nonnull final IMicroElement ePhase)
847 {
848 final PSPhase ret = new PSPhase ();
849
850 final PSRichGroup aRichGroup = new PSRichGroup ();
851 ePhase.forAllAttributes ( (sNS, sAttrName, sVal) -> {
852 final String sAttrValue = _getAttributeValue (sVal);
853 if (sAttrName.equals (CSchematronXML.ATTR_ID))
854 ret.setID (sAttrValue);
855 else
856 if (PSRichGroup.isRichAttribute (sAttrName))
857 _handleRichGroup (sAttrName, sAttrValue, aRichGroup);
858 else
859 ret.addForeignAttribute (sAttrName, sAttrValue);
860 });
861 ret.setRich (aRichGroup);
862
863 ePhase.forAllChildElements (ePhaseChild -> {
864 if (CSchematron.NAMESPACE_SCHEMATRON.equals (ePhaseChild.getNamespaceURI ()))
865 {
866 if (ePhaseChild.getLocalName ().equals (CSchematronXML.ELEMENT_INCLUDE))
867 ret.addInclude (readIncludeFromXML (ePhaseChild));
868 else
869 if (ePhaseChild.getLocalName ().equals (CSchematronXML.ELEMENT_P))
870 ret.addP (readPFromXML (ePhaseChild));
871 else
872 if (ePhaseChild.getLocalName ().equals (CSchematronXML.ELEMENT_LET))
873 ret.addLet (readLetFromXML (ePhaseChild));
874 else
875 if (ePhaseChild.getLocalName ().equals (CSchematronXML.ELEMENT_ACTIVE))
876 ret.addActive (readActiveFromXML (ePhaseChild));
877 else
878 _warn (ret, "Unsupported Schematron element '" + ePhaseChild.getLocalName () + "'");
879 }
880 else
881 ret.addForeignElement (ePhaseChild.getClone ());
882 });
883 return ret;
884 }
885
886
887
888
889
890
891
892
893 @Nonnull
894 public PSRule readRuleFromXML (@Nonnull final IMicroElement eRule)
895 {
896 final PSRule ret = new PSRule ();
897
898 final PSRichGroup aRichGroup = new PSRichGroup ();
899 final PSLinkableGroup aLinkableGroup = new PSLinkableGroup ();
900 eRule.forAllAttributes ( (sNS, sAttrName, sVal) -> {
901 final String sAttrValue = _getAttributeValue (sVal);
902 if (sAttrName.equals (CSchematronXML.ATTR_FLAG))
903 ret.setFlag (sAttrValue);
904 else
905 if (sAttrName.equals (CSchematronXML.ATTR_ABSTRACT))
906 ret.setAbstract (StringParser.parseBool (sAttrValue));
907 else
908 if (sAttrName.equals (CSchematronXML.ATTR_CONTEXT))
909 ret.setContext (sAttrValue);
910 else
911 if (sAttrName.equals (CSchematronXML.ATTR_ID))
912 ret.setID (sAttrValue);
913 else
914 if (PSRichGroup.isRichAttribute (sAttrName))
915 _handleRichGroup (sAttrName, sAttrValue, aRichGroup);
916 else
917 if (PSLinkableGroup.isLinkableAttribute (sAttrName))
918 _handleLinkableGroup (sAttrName, sAttrValue, aLinkableGroup);
919 else
920 ret.addForeignAttribute (sAttrName, sAttrValue);
921 });
922 ret.setRich (aRichGroup);
923 ret.setLinkable (aLinkableGroup);
924
925 eRule.forAllChildElements (eRuleChild -> {
926 if (CSchematron.NAMESPACE_SCHEMATRON.equals (eRuleChild.getNamespaceURI ()))
927 {
928 final String sLocalName = eRuleChild.getLocalName ();
929 if (sLocalName.equals (CSchematronXML.ELEMENT_INCLUDE))
930 ret.addInclude (readIncludeFromXML (eRuleChild));
931 else
932 if (sLocalName.equals (CSchematronXML.ELEMENT_LET))
933 ret.addLet (readLetFromXML (eRuleChild));
934 else
935 if (sLocalName.equals (CSchematronXML.ELEMENT_ASSERT) || sLocalName.equals (CSchematronXML.ELEMENT_REPORT))
936 ret.addAssertReport (readAssertReportFromXML (eRuleChild));
937 else
938 if (sLocalName.equals (CSchematronXML.ELEMENT_EXTENDS))
939 ret.addExtends (readExtendsFromXML (eRuleChild));
940 else
941 _warn (ret, "Unsupported Schematron element '" + sLocalName + "'");
942 }
943 else
944 ret.addForeignElement (eRuleChild.getClone ());
945 });
946 return ret;
947 }
948
949
950
951
952
953
954
955
956
957
958
959
960 @Nonnull
961 public PSSchema readSchemaFromXML (@Nonnull final IMicroElement eSchema) throws SchematronReadException
962 {
963 ValueEnforcer.notNull (eSchema, "Schema");
964 if (!CSchematron.NAMESPACE_SCHEMATRON.equals (eSchema.getNamespaceURI ()))
965 throw new SchematronReadException (m_aResource, "The passed element is not an ISO Schematron element!");
966
967 final PSSchema ret = new PSSchema (m_aResource);
968 final PSRichGroup aRichGroup = new PSRichGroup ();
969 eSchema.forAllAttributes ( (sNS, sAttrName, sVal) -> {
970 final String sAttrValue = _getAttributeValue (sVal);
971 if (sAttrName.equals (CSchematronXML.ATTR_ID))
972 ret.setID (sAttrValue);
973 else
974 if (sAttrName.equals (CSchematronXML.ATTR_SCHEMA_VERSION))
975 ret.setSchemaVersion (sAttrValue);
976 else
977 if (sAttrName.equals (CSchematronXML.ATTR_DEFAULT_PHASE))
978 ret.setDefaultPhase (sAttrValue);
979 else
980 if (sAttrName.equals (CSchematronXML.ATTR_QUERY_BINDING))
981 ret.setQueryBinding (sAttrValue);
982 else
983 if (PSRichGroup.isRichAttribute (sAttrName))
984 _handleRichGroup (sAttrName, sAttrValue, aRichGroup);
985 else
986 ret.addForeignAttribute (sAttrName, sAttrValue);
987 });
988 ret.setRich (aRichGroup);
989
990 eSchema.forAllChildElements (eSchemaChild -> {
991 if (CSchematron.NAMESPACE_SCHEMATRON.equals (eSchemaChild.getNamespaceURI ()))
992 {
993 if (eSchemaChild.getLocalName ().equals (CSchematronXML.ELEMENT_INCLUDE))
994 ret.addInclude (readIncludeFromXML (eSchemaChild));
995 else
996 if (eSchemaChild.getLocalName ().equals (CSchematronXML.ELEMENT_TITLE))
997 ret.setTitle (readTitleFromXML (eSchemaChild));
998 else
999 if (eSchemaChild.getLocalName ().equals (CSchematronXML.ELEMENT_NS))
1000 ret.addNS (readNSFromXML (eSchemaChild));
1001 else
1002 if (eSchemaChild.getLocalName ().equals (CSchematronXML.ELEMENT_P))
1003 {
1004 final PSP aP = readPFromXML (eSchemaChild);
1005 if (ret.hasNoPatterns ())
1006 ret.addStartP (aP);
1007 else
1008 ret.addEndP (aP);
1009 }
1010 else
1011 if (eSchemaChild.getLocalName ().equals (CSchematronXML.ELEMENT_LET))
1012 ret.addLet (readLetFromXML (eSchemaChild));
1013 else
1014 if (eSchemaChild.getLocalName ().equals (CSchematronXML.ELEMENT_PHASE))
1015 ret.addPhase (readPhaseFromXML (eSchemaChild));
1016 else
1017 if (eSchemaChild.getLocalName ().equals (CSchematronXML.ELEMENT_PATTERN))
1018 ret.addPattern (readPatternFromXML (eSchemaChild));
1019 else
1020 if (eSchemaChild.getLocalName ().equals (CSchematronXML.ELEMENT_DIAGNOSTICS))
1021 ret.setDiagnostics (readDiagnosticsFromXML (eSchemaChild));
1022 else
1023 _warn (ret, "Unsupported Schematron element '" + eSchemaChild.getLocalName () + "'");
1024 }
1025 else
1026 ret.addForeignElement (eSchemaChild.getClone ());
1027 });
1028 return ret;
1029 }
1030
1031
1032
1033
1034
1035
1036
1037
1038 @Nonnull
1039 public PSSpan readSpanFromXML (@Nonnull final IMicroElement eSpan)
1040 {
1041 final PSSpan ret = new PSSpan ();
1042
1043 eSpan.forAllAttributes ( (sNS, sAttrName, sVal) -> {
1044 final String sAttrValue = _getAttributeValue (sVal);
1045 if (sAttrName.equals (CSchematronXML.ATTR_CLASS))
1046 ret.setClazz (sAttrValue);
1047 else
1048 ret.addForeignAttribute (sAttrName, sAttrValue);
1049 });
1050
1051 eSpan.forAllChildren (aSpanChild -> {
1052 switch (aSpanChild.getType ())
1053 {
1054 case TEXT:
1055 ret.addText (((IMicroText) aSpanChild).getNodeValue ());
1056 break;
1057 case ELEMENT:
1058 final IMicroElement eElement = (IMicroElement) aSpanChild;
1059 if (CSchematron.NAMESPACE_SCHEMATRON.equals (eElement.getNamespaceURI ()))
1060 {
1061 _warn (ret, "Unsupported Schematron element '" + eElement.getLocalName () + "'");
1062 }
1063 else
1064 ret.addForeignElement (eElement.getClone ());
1065
1066 break;
1067 case COMMENT:
1068
1069 break;
1070 default:
1071 _warn (ret, "Unsupported child node: " + aSpanChild);
1072 }
1073 });
1074 return ret;
1075 }
1076
1077
1078
1079
1080
1081
1082
1083
1084 @Nonnull
1085 public PSTitle readTitleFromXML (@Nonnull final IMicroElement eTitle)
1086 {
1087 final PSTitle ret = new PSTitle ();
1088
1089 eTitle.forAllAttributes ( (sNS, sAttrName, sVal) -> {
1090 final String sAttrValue = _getAttributeValue (sVal);
1091 _warn (ret, "Unsupported attribute '" + sAttrName + "'='" + sAttrValue + "'");
1092 });
1093
1094 eTitle.forAllChildren (aTitleChild -> {
1095 switch (aTitleChild.getType ())
1096 {
1097 case TEXT:
1098 ret.addText (((IMicroText) aTitleChild).getNodeValue ());
1099 break;
1100 case ELEMENT:
1101 final IMicroElement eElement = (IMicroElement) aTitleChild;
1102 if (CSchematron.NAMESPACE_SCHEMATRON.equals (eElement.getNamespaceURI ()))
1103 {
1104 final String sLocalName = eElement.getLocalName ();
1105 if (sLocalName.equals (CSchematronXML.ELEMENT_DIR))
1106 ret.addDir (readDirFromXML (eElement));
1107 else
1108 _warn (ret, "Unsupported Schematron element '" + sLocalName + "'");
1109 }
1110 else
1111 _warn (ret, "Unsupported namespace URI '" + eElement.getNamespaceURI () + "'");
1112
1113 break;
1114 case COMMENT:
1115
1116 break;
1117 default:
1118 _warn (ret, "Unsupported child node: " + aTitleChild);
1119 }
1120 });
1121 return ret;
1122 }
1123
1124
1125
1126
1127
1128
1129
1130
1131 @Nonnull
1132 public PSValueOf readValueOfFromXML (@Nonnull final IMicroElement eValueOf)
1133 {
1134 final PSValueOf ret = new PSValueOf ();
1135
1136 eValueOf.forAllAttributes ( (sNS, sAttrName, sVal) -> {
1137 final String sAttrValue = _getAttributeValue (sVal);
1138 if (sAttrName.equals (CSchematronXML.ATTR_SELECT))
1139 ret.setSelect (sAttrValue);
1140 else
1141 ret.addForeignAttribute (sAttrName, sAttrValue);
1142 });
1143
1144 eValueOf.forAllChildElements (eValueOfChild -> {
1145 if (CSchematron.NAMESPACE_SCHEMATRON.equals (eValueOfChild.getNamespaceURI ()))
1146 {
1147 _warn (ret, "Unsupported Schematron element '" + eValueOfChild.getLocalName () + "'");
1148 }
1149 else
1150 _warn (ret, "Unsupported namespace URI '" + eValueOfChild.getNamespaceURI () + "'");
1151 });
1152 return ret;
1153 }
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164 @Nonnull
1165 public PSSchema readSchema () throws SchematronReadException
1166 {
1167
1168 final SAXReaderSettings aSettings = new SAXReaderSettings ().setEntityResolver (m_aEntityResolver);
1169
1170 final IMicroDocument aDoc = SchematronHelper.getWithResolvedSchematronIncludes (m_aResource,
1171 aSettings,
1172 m_aErrorHandler);
1173 if (aDoc == null || aDoc.getDocumentElement () == null)
1174 throw new SchematronReadException (m_aResource, "Failed to resolve includes in resource " + m_aResource);
1175
1176 if (SchematronDebug.isShowResolvedSourceSchematron ())
1177 s_aLogger.info ("Resolved source Schematron:\n" + MicroWriter.getNodeAsString (aDoc));
1178
1179 return readSchemaFromXML (aDoc.getDocumentElement ());
1180 }
1181
1182 @Override
1183 public String toString ()
1184 {
1185 return new ToStringGenerator (this).append ("resource", m_aResource)
1186 .append ("errorHandler", m_aErrorHandler)
1187 .getToString ();
1188 }
1189 }