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