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