Annotation of xmlschema/alternate.py, revision 1.7.2.1
1.1 ht 1: # Build class instances from an alternating normal form XML document
1.7.2.1 ! ht 2: # $Id: alternate.py,v 1.7 2002/02/02 16:33:56 ht Exp $
1.1 ht 3:
4: # Note that we get lists in TWO cases:
5: # 1) multiple rel elements with same name
6: # 2) multiple daughters of single rel element
7:
8: import PyLTXML
9: import types
10:
1.4 ht 11: NilVal=(None,)
12:
1.1 ht 13: def fromAltFile(filename,relMap,constructInd,root=None):
1.2 ht 14: flags=(PyLTXML.NSL_read|PyLTXML.NSL_read_namespaces)
1.1 ht 15: try:
16: file=PyLTXML.Open(filename,None,flags)
17: except:
18: return
19: # try:
20: if root:
21: buildRels(file,root,relMap,constructInd)
22: else:
23: root=buildInd(file,relMap,constructInd)
24: # except:
25: # root=None
26: # try:
27: if root and file.seenValidityError:
28: root=None
29: # except:
30: # pass
31: # try:
32: PyLTXML.Close(file)
33: # except:
34: # pass
35: return root
36:
37: def buildRels(file,ind,relMap,constructInd):
38: b = PyLTXML.GetNextBit(file)
39: down=0
40: while b:
41: if b.type == "start" or b.type == "empty":
42: if down:
43: # multiple values
44: rval=buildInd(file,relMap,constructInd,b)
45: else:
46: # print ('br',b.llabel)
47: lab=str(b.llabel)
48: if relMap.has_key(lab):
49: lab=relMap[lab]
50: if b.type=="start":
51: rval=buildInd(file,relMap,constructInd)
1.2 ht 52: elif PyLTXML.GetAttrVal(b.item,'xsi:nil')=='true':
1.4 ht 53: rval=NilVal
1.1 ht 54: else:
55: rval=""
56: # three cases -- a) this rel was empty; b) this rel had text content;
57: # c) this rel had an ind elt content
58: # In case (a) and (b) the end tag is not there/consumed, case (c) it's
59: # still to come
60: if b.type=="start" and (type(rval)==types.InstanceType or not rval):
61: down=1
1.7.2.1 ! ht 62: # print ('bir',rval,lab,ind.__dict__.has_key(lab))
1.5 ht 63: if ind.__dict__.has_key(lab) and (getattr(ind,lab) is not None):
1.2 ht 64: # Can't use hasattr because that finds the class defaults
65: # But what about non-null defaults at the __init__ level?
1.1 ht 66: ov=getattr(ind,lab)
67: if type(ov)==types.ListType:
68: ov.append(rval)
69: else:
70: setattr(ind,lab,[ov,rval])
71: else:
72: setattr(ind,lab,rval)
73: elif b.type == "end":
74: # if we have one or more inds as value, this is just this rel's end
75: if down:
76: down=0
77: else:
78: # we're done
79: return
80: elif b.type == "bad":
81: raise Exception, "parse error"
82: # note we ignore pis, comments, text -- text is whitespace or broken
83: b = PyLTXML.GetNextBit(file)
84: # better be the top rel finishing . . .
85:
86: def buildInd(file,relMap,constructInd,b=None):
87: if not b:
88: b = PyLTXML.GetNextBit(file)
89: text=""
90: while b:
91: if b.type == "start" or b.type == "empty":
92: # print ('bi',b.llabel)
93: inst=constructInd(b.llabel,b.item)
1.3 ht 94: # is this too XMLSchema-specific? Note we can't handle this in
95: # Component.rebuild itself, as there are circular references
1.5 ht 96: if inst is not None and inst.reffed:
1.3 ht 97: inst.reffed=0
98: rebuild=0
99: else:
100: rebuild=1
1.1 ht 101: if b.type=="start":
1.5 ht 102: if inst is not None:
1.1 ht 103: buildRels(file,inst,relMap,constructInd)
104: # buildRels consumes our end tag
105: else:
106: # skip this, assume non-recursive
107: lab=b.label
108: b=PyLTXML.GetNextBit(file)
1.5 ht 109: while b is not None and (b.type!="end" or b.label!=lab):
1.1 ht 110: b=PyLTXML.GetNextBit(file)
1.6 ht 111: if rebuild and (inst is not None) and inst.rebuild:
112: inst.rebuild()
1.1 ht 113: return inst
114: elif b.type=="text":
115: text=b.body
116: elif b.type=="end":
117: # we were text only, return it
118: # print ('bt',text)
119: return text
120: elif b.type == "bad":
121: raise Exception, "parse error"
122: b = PyLTXML.GetNextBit(file)
123: # shouldn't be possible to fall out without errror
124: raise Exception, "oops, ran off end of XML file"
1.7 ht 125:
126: def av(item,name):
127: return PyLTXML.GetAttrVal(item,name)
Webmaster