1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 import string
22 from xml.dom import pulldom
23
24 from pywbem import cim_obj
25 from pywbem.cim_obj import CIMInstance, CIMInstanceName, CIMQualifier, \
26 CIMProperty
27
28 __all__ = ['ParseError', 'make_parser', 'parse_any']
29
31 """This exception is raised when there is a validation error detected
32 by the parser."""
33 pass
34
35
36
37
38
40 """Return an attribute by name. Throw an exception if not present."""
41
42 if not node.hasAttribute(attr):
43 raise ParseError(
44 'Expecting %s attribute in element %s' % (attr, node.tagName))
45
46 return node.getAttribute(attr)
47
49 """Return an attribute by name, or None if not present."""
50
51 if node.hasAttribute(attr):
52 return node.getAttribute(attr)
53
54 return None
55
57 """Check that the next event is the end of a particular tag."""
58
59 (event, node) = parser.next()
60
61 if event != pulldom.END_ELEMENT or node.tagName != tagName:
62 raise ParseError(
63 'Expecting %s end tag, got %s %s' % (tagName, event, node.tagName))
64
66 """Return true if (event, node) is a start event for tagname."""
67 return event == pulldom.START_ELEMENT and node.tagName == tagName
68
70 """Return true if (event, node) is an end event for tagname."""
71 return event == pulldom.END_ELEMENT and node.tagName == tagName
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
120
121 value = ''
122
123 (next_event, next_node) = parser.next()
124
125 if next_event == pulldom.CHARACTERS:
126
127 value = next_node.nodeValue
128
129 (next_event, next_node) = parser.next()
130
131 if not _is_end(next_event, next_node, 'VALUE'):
132 raise ParseError('Expecting end VALUE')
133
134 return value
135
136
137
139
140 value_array = []
141
142 (next_event, next_node) = parser.next()
143
144 if _is_start(next_event, next_node, 'VALUE'):
145
146 value_array.append(parse_value(parser, next_event, next_node))
147
148 while 1:
149
150 (next_event, next_node) = parser.next()
151
152 if _is_end(next_event, next_node, 'VALUE.ARRAY'):
153 break
154
155 if _is_start(next_event, next_node, 'VALUE'):
156 value_array.append(parse_value(parser, next_event, next_node))
157 else:
158 raise ParseError('Expecting VALUE element')
159
160 return value_array
161
162
163
164
166
167 (next_event, next_node) = parser.next()
168
169 if _is_start(next_event, next_node, 'CLASSPATH'):
170 result = parse_classpath(parser, next_event, next_node)
171
172 elif _is_start(next_event, next_node, 'LOCALCLASSPATH'):
173 result = parse_localclasspath(parser, next_event, next_node)
174
175 elif _is_start(next_event, next_node, 'CLASSNAME'):
176 result = parse_classname(parser, next_event, next_node)
177
178 elif _is_start(next_event, next_node, 'INSTANCEPATH'):
179 result = parse_instancepath(parser, next_event, next_node)
180
181 elif _is_start(next_event, next_node, 'LOCALINSTANCEPATH'):
182 result = parse_localinstancepath(parser, next_event, next_node)
183
184 elif _is_start(next_event, next_node, 'INSTANCENAME'):
185 result = parse_instancename(parser, next_event, next_node)
186
187 else:
188 raise ParseError('Expecting (CLASSPATH | LOCALCLASSPATH | CLASSNAME '
189 '| INSTANCEPATH | LOCALINSTANCEPATH | INSTANCENAME)')
190
191 _get_end_event(parser, 'VALUE.REFERENCE')
192
193 return result
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
212
213 (next_event, next_node) = parser.next()
214
215 if not _is_start(next_event, next_node, 'HOST'):
216 raise ParseError('Expecting HOST')
217
218 host = parse_host(parser, next_event, next_node)
219
220 (next_event, next_node) = parser.next()
221
222 if not _is_start(next_event, next_node, 'LOCALNAMESPACEPATH'):
223 raise ParseError('Expecting LOCALNAMESPACEPATH')
224
225 namespacepath = parse_localnamespacepath(parser, next_event, next_node)
226
227 (next_event, next_node) = parser.next()
228
229 if not _is_end(next_event, next_node, 'NAMESPACEPATH'):
230 raise ParseError('Expecting end NAMESPACEPATH')
231
232 return (host, namespacepath)
233
234
235
237
238 (next_event, next_node) = parser.next()
239
240 namespaces = []
241
242 if not _is_start(next_event, next_node, 'NAMESPACE'):
243 print next_event, next_node
244 raise ParseError('Expecting NAMESPACE')
245
246 namespaces.append(parse_namespace(parser, next_event, next_node))
247
248 while 1:
249
250 (next_event, next_node) = parser.next()
251
252 if _is_end(next_event, next_node, 'LOCALNAMESPACEPATH'):
253 break
254
255 if _is_start(next_event, next_node, 'NAMESPACE'):
256 namespaces.append(parse_namespace(parser, next_event, next_node))
257 else:
258 raise ParseError('Expecting NAMESPACE')
259
260 return string.join(namespaces, '/')
261
262
263
265
266 host = ''
267
268 (next_event, next_node) = parser.next()
269
270 if next_event == pulldom.CHARACTERS:
271
272 host = next_node.nodeValue
273
274 (next_event, next_node) = parser.next()
275
276 if not _is_end(next_event, next_node, 'HOST'):
277 raise ParseError('Expecting end HOST')
278
279 return host
280
281
282
283
284
285
287
288 name = _get_required_attribute(node, 'NAME')
289
290 (next_event, next_node) = parser.next()
291
292 if not _is_end(next_event, next_node, 'NAMESPACE'):
293 raise ParseError('Expecting end NAMESPACE')
294
295 return name
296
297
298
299
300
301
302
303
304
305
306
307
309
310 (next_event, next_node) = parser.next()
311
312 if not _is_start(next_event, next_node, 'NAMESPACEPATH'):
313 raise ParseError('Expecting NAMESPACEPATH')
314
315 host, namespacepath = parse_namespacepath(parser, next_event, next_node)
316
317 (next_event, next_node) = parser.next()
318
319 if not _is_start(next_event, next_node, 'INSTANCENAME'):
320 print next_event, next_node
321 raise ParseError('Expecting INSTANCENAME')
322
323 instancename = parse_instancename(parser, next_event, next_node)
324
325 instancename.host = host
326 instancename.namespace = namespacepath
327
328 return instancename
329
330
331
333
334 (next_event, next_node) = parser.next()
335
336 if not _is_start(next_event, next_node, 'LOCALNAMESPACEPATH'):
337 raise ParseError('Expecting LOCALNAMESPACEPATH')
338
339 namespacepath = parse_localnamespacepath(parser, next_event, next_node)
340
341 (next_event, next_node) = parser.next()
342
343 if not _is_start(next_event, next_node, 'INSTANCENAME'):
344 raise ParseError('Expecting INSTANCENAME')
345
346 instancename = parse_instancename(parser, next_event, next_node)
347
348 instancename.namespace = namespacepath
349
350 return instancename
351
352
353
354
355
356
358
359 classname = _get_required_attribute(node, 'CLASSNAME')
360 keybindings = []
361
362 (next_event, next_node) = parser.next()
363
364 if _is_start(next_event, next_node, 'KEYBINDING'):
365
366 keybindings.append(parse_keybinding(parser, next_event, next_node))
367
368 while 1:
369
370 (next_event, next_node) = parser.next()
371
372 if _is_end(next_event, next_node, 'INSTANCENAME'):
373 break
374
375 if _is_start(next_event, next_node, 'KEYBINDING'):
376 keybindings.append(
377 parse_keybinding(parser, next_event, next_node))
378 else:
379 raise ParseError('Expecting KEYBINDING element')
380
381 if _is_end(next_event, next_node, 'INSTANCENAME'):
382 pass
383
384 elif _is_start(next_event, next_node, 'KEYVALUE'):
385 keybindings.append(('', parse_keyvalue(parser, next_event, next_node)))
386
387 elif _is_start(next_event, next_node, 'VALUE.REFERENCE'):
388 keybindings.append(
389 parse_value_reference(parser, next_event, next_node))
390
391 else:
392 raise ParseError(
393 'Expecting KEYBINDING* | KEYVALUE? | VALUE.REFERENCE')
394
395 return CIMInstanceName(classname, keybindings)
396
397
398
399
400
401
402
403
405
406 name = _get_required_attribute(node, 'NAME')
407
408 (next_event, next_node) = parser.next()
409
410 if _is_start(next_event, next_node, 'KEYVALUE'):
411 keyvalue = parse_keyvalue(parser, next_event, next_node)
412 result = (name, keyvalue)
413
414 elif _is_start(next_event, next_node, 'VALUE.REFERENCE'):
415 value_reference = parse_value_reference(parser, next_event, next_node)
416 result = (name, value_reference)
417
418 else:
419 raise ParseError('Expecting KEYVALUE or VALUE.REFERENCE element')
420
421 _get_end_event(parser, 'KEYBINDING')
422
423 return result
424
425
426
427
428
429
430
432
433 valuetype = _get_required_attribute(node, 'VALUETYPE')
434 type = _get_attribute(node, 'TYPE')
435
436 (next_event, next_node) = parser.next()
437
438 if next_event != pulldom.CHARACTERS:
439 raise ParseError('Expecting character data')
440
441 value = next_node.nodeValue
442
443 if valuetype == 'string':
444 pass
445
446 elif valuetype == 'boolean':
447
448
449
450
451
452 p = value.strip().lower()
453
454 if p == 'true':
455 value = True
456 elif p == 'false':
457 value = False
458 else:
459 raise ParseError('invalid boolean value "%s"' % `p`)
460
461 elif valuetype == 'numeric':
462
463 try:
464
465
466
467
468
469
470
471
472 value = int(value.strip(), 0)
473
474 except ValueError:
475 raise ParseError(
476 'invalid numeric value "%s"' % value)
477
478 else:
479 raise ParseError('Invalid VALUETYPE')
480
481 _get_end_event(parser, 'KEYVALUE')
482
483 return value
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
504
505 classname = _get_required_attribute(node, 'CLASSNAME')
506
507 properties = []
508 qualifiers = []
509
510 (next_event, next_node) = parser.next()
511
512 if _is_start(next_event, next_node, 'QUALIFIER'):
513
514 qualifiers.append(parse_qualifier(parser, next_event, next_node))
515
516 while 1:
517
518 (next_event, next_node) = parser.next()
519
520 if _is_start(next_event, next_node, 'PROPERTY') or \
521 _is_start(next_event, next_node, 'PROPERTY.ARRAY') or \
522 _is_start(next_event, next_node, 'PROPERTY.REFERENCE') or \
523 _is_end(next_event, next_node, 'INSTANCE'):
524 break
525
526 if _is_start(next_event, next_node, 'QUALIFIER'):
527 qualifiers.append(
528 parse_qualifier(parser, next_event, next_node))
529 else:
530 raise ParseError('Expecting QUALIFIER')
531
532 while 1:
533
534 if _is_end(next_event, next_node, 'INSTANCE'):
535 break
536
537 if _is_start(next_event, next_node, 'PROPERTY'):
538 properties.append(parse_property(parser, next_event, next_node))
539
540 elif _is_start(next_event, next_node, 'PROPERTY.ARRAY'):
541 properties.append(
542 parse_property_array(parser, next_event, next_node))
543
544 elif _is_start(next_event, next_node, 'PROPERTY.REFERENCE'):
545 properties.append(
546 parse_property_reference(parser, next_event, next_node))
547 else:
548 raise ParseError(
549 'Expecting (PROPERTY | PROPERTY.ARRAY | PROPERTY.REFERENCE)')
550
551 (next_event, next_node) = parser.next()
552
553 if not _is_end(next_event, next_node, 'INSTANCE'):
554 raise ParseError('Expecting end INSTANCE')
555
556 return CIMInstance(
557 classname,
558 properties=dict([(x.name, x) for x in properties]),
559 qualifiers=dict([(x.name, x) for x in qualifiers]))
560
561
562
563
564
565
566
567
568
569
571
572 name = _get_required_attribute(node, 'NAME')
573 type = _get_required_attribute(node, 'TYPE')
574 propagated = _get_attribute(node, 'PROPAGATED')
575
576 (next_event, next_node) = parser.next()
577
578 if _is_end(next_event, next_node, 'QUALIFIER'):
579 return CIMQualifier(name, None, type=type)
580
581 if _is_start(next_event, next_node, 'VALUE'):
582 value = parse_value(parser, next_event, next_node)
583 elif _is_start(next_event, next_node, 'VALUE.ARRAY'):
584 value = parse_value_array(parser, next_event, next_node)
585 else:
586 raise ParseError('Expecting (VALUE | VALUE.ARRAY)')
587
588 result = CIMQualifier(name, cim_obj.tocimobj(type, value))
589
590 _get_end_event(parser, 'QUALIFIER')
591
592 return result
593
594
595
596
597
598
599
600
601
602
604
605 name = _get_required_attribute(node, 'NAME')
606 type = _get_required_attribute(node, 'TYPE')
607
608 class_origin = _get_attribute(node, 'CLASSORIGIN')
609 propagated = _get_attribute(node, 'PROPAGATED')
610
611 qualifiers = []
612 value = None
613
614 (next_event, next_node) = parser.next()
615
616 if _is_start(next_event, next_node, 'QUALIFIER'):
617
618 qualifiers.append(parse_qualifier(parser, next_event, next_node))
619
620 while 1:
621
622 (next_event, next_node) = parser.next()
623
624 if _is_start(next_event, next_node, 'VALUE'):
625 break
626
627 if _is_start(next_event, next_node, 'QUALIFIER'):
628 qualifiers.append(
629 parse_qualifier(parser, next_event, next_node))
630 else:
631 raise ParseError('Expecting QUALIFIER')
632
633 if _is_start(next_event, next_node, 'VALUE'):
634
635 value = parse_value(parser, next_event, next_node)
636 (next_event, next_node) = parser.next()
637
638 if not _is_end(next_event, next_node, 'PROPERTY'):
639 raise ParseError('Expecting end PROPERTY')
640
641 return CIMProperty(
642 name,
643 cim_obj.tocimobj(type, value),
644 type=type,
645 class_origin=class_origin,
646 propagated=propagated,
647 qualifiers=dict([(x.name, x) for x in qualifiers]))
648
649
650
651
652
653
654
655
656
657
658
660
661 name = _get_required_attribute(node, 'NAME')
662 type = _get_required_attribute(node, 'TYPE')
663
664 array_size = _get_attribute(node, 'ARRAYSIZE')
665 class_origin = _get_attribute(node, 'CLASSORIGIN')
666 propagated = _get_attribute(node, 'PROPAGATED')
667
668 qualifiers = []
669 value = None
670
671 (next_event, next_node) = parser.next()
672
673 if _is_start(next_event, next_node, 'QUALIFIER'):
674
675 qualifiers.append(parse_qualifier(parser, next_event, next_node))
676
677 while 1:
678
679 (next_event, next_node) = parser.next()
680
681 if _is_start(next_event, next_node, 'VALUE.ARRAY'):
682 break
683
684 if _is_start(next_event, next_node, 'QUALIFIER'):
685 qualifiers.append(
686 parse_qualifier(parser, next_event, next_node))
687 else:
688 raise ParseError('Expecting QUALIFIER')
689
690 if _is_start(next_event, next_node, 'VALUE.ARRAY'):
691
692 value = parse_value_array(parser, next_event, next_node)
693 (next_event, next_node) = parser.next()
694
695 if not _is_end(next_event, next_node, 'PROPERTY.ARRAY'):
696 raise ParseError('Expecting end PROPERTY.ARRAY')
697
698 return CIMProperty(
699 name,
700 cim_obj.tocimobj(type, value),
701 type=type,
702 class_origin=class_origin,
703 propagated=propagated,
704 is_array=True,
705 qualifiers=dict([(x.name, x) for x in qualifiers]))
706
707
708
709
710
711
712
713
714
716
717 name = _get_required_attribute(node, 'NAME')
718
719 class_origin = _get_attribute(node, 'CLASSORIGIN')
720 propagated = _get_attribute(node, 'PROPAGATED')
721
722 qualifiers = []
723 value = None
724
725 (next_event, next_node) = parser.next()
726
727 if _is_start(next_event, next_node, 'QUALIFIER'):
728
729 qualifiers.append(parse_qualifier(parser, next_event, next_node))
730
731 while 1:
732
733 (next_event, next_node) = parser.next()
734
735 if _is_start(next_event, next_node, 'VALUE.REFERENCE'):
736 break
737
738 if _is_start(next_event, next_node, 'QUALIFIER'):
739 qualifiers.append(
740 parse_qualifier(parser, next_event, next_node))
741
742 else:
743 raise ParseError('Expecting QUALIFIER')
744
745 if _is_start(next_event, next_node, 'VALUE.REFERENCE'):
746
747 value = parse_value_reference(parser, next_event, next_node)
748 (next_event, next_node) = parser.next()
749
750 if not _is_end(next_event, next_node, 'PROPERTY.REFERENCE'):
751 raise ParseError('Expecting end PROPERTY.REFERENCE')
752
753 return CIMProperty(
754 name,
755 value,
756 class_origin=class_origin,
757 propagated=propagated,
758 type='reference',
759 qualifiers=dict([(x.name, x) for x in qualifiers]))
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
926 """Create a xml.dom.pulldom parser."""
927
928 if type(stream_or_string) == str or type(stream_or_string) == unicode:
929
930
931
932
933 return pulldom.parseString(str(stream_or_string))
934
935 else:
936
937 return pulldom.parse(stream_or_string)
938
940 """Parse any XML string or stream."""
941
942 parser = make_parser(stream_or_string)
943
944 (event, node) = parser.next()
945
946 if event != pulldom.START_DOCUMENT:
947 raise ParseError('Expecting document start')
948
949 (event, node) = parser.next()
950
951 if event != pulldom.START_ELEMENT:
952 raise ParseError('Expecting element start')
953
954 fn_name = 'parse_%s' % node.tagName.lower().replace('.', '_')
955 fn = globals().get(fn_name)
956 if fn is None:
957 raise ParseError('No parser for element %s' % node.tagName)
958
959 return fn(parser, event, node)
960
961
962
963 if __name__ == '__main__':
964 import sys
965 print parse_any(sys.stdin)
966