def cofeed(self, obj, prefixes=None): """ Feed a structure to the writer, including a cursor. The structure is interpreted as XML and serialized. The initially fed structure becomes the outer envelope of the serialized XML, and then the operation is suspended (this method engenders a coroutine). The user can then send additional substructures to the coroutine, which get serialized at the point of the cursor, until the user closes the coroutine, at which point the serialization is completed. obj - XML node proxy structure (or iterator thereof), such as amara.writers.struct.ROOT (proxy for a root (entity) node), amara.writers.struct.E (proxy for an element), or amara.writers.struct.E_CURSOR (proxy for a cursor element, whose children are then later provided by sending proxy nodes to the coroutine). See documentation for other proxy node classes """ #This method is largely a dupe of feed, but rather than calling self.feed to #recursively deal with compound structures, it sets up a child coroutine #and forwards values sent by the parent. There is a lot of inelegant #duplication because we often can't tidy things up with functions without #Breaking the character of cofeed as a coroutine #this is one are where Python could very much use cpp-style macros #FIXME. There is some inelegant duplication that might well be refatcored #away, even without the benefit of cpp-style macros prefixes = prefixes or {} if isinstance(obj, ROOT): self.printer.start_document() for subobj in obj.content: try: buf = self.cofeed(subobj, prefixes=None) try: while True: val = (yield) buf.send(val) except GeneratorExit: buf.close() except StopIteration: pass #self.feed(subobj) self.printer.end_document() return if isinstance(obj, NS): return if isinstance(obj, RAW): doc = amara.parse(obj.content) from amara.writers._treevisitor import visitor v = visitor(printer=self.printer) for child in doc.xml_children: v.visit(child) return if isinstance(obj, E_CURSOR): new_prefixes = [] prefix, local = splitqname(obj.qname) prefix = prefix or u'' if obj.ns == UNSPECIFIED_NAMESPACE: obj.ns = prefixes.get(prefix, u'') elif prefix not in prefixes or prefixes[prefix] != obj.ns: new_prefixes.append((prefix, obj.ns or u'')) attrs = [a for a in obj.attributes.itervalues() ] if obj.attributes else () if new_prefixes: prefixes = prefixes.copy() prefixes.update(dict(new_prefixes)) self.printer.start_element(obj.ns, obj.qname, new_prefixes, attrs) try: buf = obj.do(self) while True: val = (yield) buf.send(val) except GeneratorExit: buf.close() self.printer.end_element(obj.ns, obj.qname) return if isinstance(obj, E): #First attempt used tee. Seems we ran into the warning at #http://www.python.org/doc/2.4.3/whatsnew/node13.html #"Note that tee() has to keep copies of the values returned by the iterator; #in the worst case, it may need to keep all of them. #This should therefore be used carefully if the leading iterator can run #far ahead of the trailing iterator in a long stream of inputs. #If the separation is large, then you might as well use list() instead. #When the iterators track closely with one another, tee()" is ideal. Possible #applications include bookmarking, windowing, or lookahead iterators. #(Contributed by Raymond Hettinger.)" #obj.namespaces = {} new_prefixes = [] lead = None content = iter(obj.content) for subobj in content: if isinstance(subobj, NS): new_prefixes.append((subobj.prefix, subobj.namespace)) else: lead = subobj break prefix, local = splitqname(obj.qname) prefix = prefix or u'' if obj.ns == UNSPECIFIED_NAMESPACE: obj.ns = prefixes.get(prefix, u'') elif prefix not in prefixes or prefixes[prefix] != obj.ns: new_prefixes.append((prefix, obj.ns or u'')) attrs = [a for a in obj.attributes.itervalues() ] if obj.attributes else () if new_prefixes: prefixes = prefixes.copy() prefixes.update(dict(new_prefixes)) self.printer.start_element(obj.ns, obj.qname, new_prefixes, attrs) if lead: if isinstance(lead, E_CURSOR) or isinstance(lead, E): try: buf = self.cofeed(lead, prefixes=None) try: while True: val = (yield) buf.send(val) except GeneratorExit: buf.close() except StopIteration: pass else: self.feed(lead, prefixes) for subobj in content: if isinstance(subobj, E_CURSOR) or isinstance(subobj, E): try: buf = self.cofeed(subobj, prefixes=None) try: while True: val = (yield) buf.send(val) except GeneratorExit: buf.close() except StopIteration: pass else: self.feed(subobj, prefixes) self.printer.end_element(obj.ns, obj.qname) return if isinstance(obj, basestring): self.printer.text(U(obj)) return if isinstance(obj, tree.element): #Be smart about bindery nodes self.printer.text(unicode(obj)) return try: obj = iter(obj) except TypeError, e: if callable(obj): self.feed(obj(), prefixes) else: #Just try to make it text, i.e. punt self.feed(unicode(obj), prefixes)
def cofeed(self, obj, prefixes=None): """ Feed a structure to the writer, including a cursor. The structure is interpreted as XML and serialized. The initially fed structure becomes the outer envelope of the serialized XML, and then the operation is suspended (this method engenders a coroutine). The user can then send additional substructures to the coroutine, which get serialized at the point of the cursor, until the user closes the coroutine, at which point the serialization is completed. obj - XML node proxy structure (or iterator thereof), such as amara.writers.struct.ROOT (proxy for a root (entity) node), amara.writers.struct.E (proxy for an element), or amara.writers.struct.E_CURSOR (proxy for a cursor element, whose children are then later provided by sending proxy nodes to the coroutine). See documentation for other proxy node classes """ #This method is largely a dupe of feed, but rather than calling self.feed to #recursively deal with compound structures, it sets up a child coroutine #and forwards values sent by the parent. There is a lot of inelegant #duplication because we often can't tidy things up with functions without #Breaking the character of cofeed as a coroutine #this is one are where Python could very much use cpp-style macros #FIXME. There is some inelegant duplication that might well be refatcored #away, even without the benefit of cpp-style macros prefixes = prefixes or {} if isinstance(obj, ROOT): self.printer.start_document() for subobj in obj.content: try: buf = self.cofeed(subobj, prefixes=None) try: while True: val = (yield) buf.send(val) except GeneratorExit: buf.close() except StopIteration: pass #self.feed(subobj) self.printer.end_document() return if isinstance(obj, NS): return if isinstance(obj, RAW): doc = amara.parse(obj.content) from amara.writers._treevisitor import visitor v = visitor(printer=self.printer) for child in doc.xml_children: v.visit(child) return if isinstance(obj, E_CURSOR): new_prefixes = [] prefix, local = splitqname(obj.qname) prefix = prefix or u'' if obj.ns == UNSPECIFIED_NAMESPACE: obj.ns = prefixes.get(prefix, u'') elif prefix not in prefixes or prefixes[prefix] != obj.ns: new_prefixes.append((prefix, obj.ns or u'')) attrs = [ a for a in obj.attributes.itervalues() ] if obj.attributes else () if new_prefixes: prefixes = prefixes.copy() prefixes.update(dict(new_prefixes)) self.printer.start_element(obj.ns, obj.qname, new_prefixes, attrs) try: buf = obj.do(self) while True: val = (yield) buf.send(val) except GeneratorExit: buf.close() self.printer.end_element(obj.ns, obj.qname) return if isinstance(obj, E): #First attempt used tee. Seems we ran into the warning at #http://www.python.org/doc/2.4.3/whatsnew/node13.html #"Note that tee() has to keep copies of the values returned by the iterator; #in the worst case, it may need to keep all of them. #This should therefore be used carefully if the leading iterator can run #far ahead of the trailing iterator in a long stream of inputs. #If the separation is large, then you might as well use list() instead. #When the iterators track closely with one another, tee()" is ideal. Possible #applications include bookmarking, windowing, or lookahead iterators. #(Contributed by Raymond Hettinger.)" #obj.namespaces = {} new_prefixes = [] lead = None content = iter(obj.content) for subobj in content: if isinstance(subobj, NS): new_prefixes.append((subobj.prefix, subobj.namespace)) else: lead = subobj break prefix, local = splitqname(obj.qname) prefix = prefix or u'' if obj.ns == UNSPECIFIED_NAMESPACE: obj.ns = prefixes.get(prefix, u'') elif prefix not in prefixes or prefixes[prefix] != obj.ns: new_prefixes.append((prefix, obj.ns or u'')) attrs = [ a for a in obj.attributes.itervalues() ] if obj.attributes else () if new_prefixes: prefixes = prefixes.copy() prefixes.update(dict(new_prefixes)) self.printer.start_element(obj.ns, obj.qname, new_prefixes, attrs) if lead: if isinstance(lead, E_CURSOR) or isinstance(lead, E): try: buf = self.cofeed(lead, prefixes=None) try: while True: val = (yield) buf.send(val) except GeneratorExit: buf.close() except StopIteration: pass else: self.feed(lead, prefixes) for subobj in content: if isinstance(subobj, E_CURSOR) or isinstance(subobj, E): try: buf = self.cofeed(subobj, prefixes=None) try: while True: val = (yield) buf.send(val) except GeneratorExit: buf.close() except StopIteration: pass else: self.feed(subobj, prefixes) self.printer.end_element(obj.ns, obj.qname) return if isinstance(obj, basestring): self.printer.text(U(obj)) return if isinstance(obj, tree.element): #Be smart about bindery nodes self.printer.text(unicode(obj)) return try: obj = iter(obj) except TypeError, e: if callable(obj): self.feed(obj(), prefixes) else: #Just try to make it text, i.e. punt self.feed(unicode(obj), prefixes)
def feed(self, obj, prefixes=None): """ Feed a structure to the writer. The structure is interpreted as XML and serialized. obj - XML node proxy structure (or iterator thereof), such as amara.writers.struct.ROOT (proxy for a root (entity) node) or amara.writers.struct.E (proxy for an element). See documentation for other proxy node classes """ prefixes = prefixes or {} if isinstance(obj, ROOT): self.printer.start_document() for subobj in obj.content: self.feed(subobj) self.printer.end_document() return if isinstance(obj, NS): return if isinstance(obj, RAW): #parse_frag returns an entity ent = parse_fragment(inputsource.text(obj.content)) from amara.writers._treevisitor import visitor v = visitor(printer=self.printer) for child in ent.xml_children: v.visit(child) return if isinstance(obj, E): #First attempt used tee. Seems we ran into the warning at #http://www.python.org/doc/2.4.3/whatsnew/node13.html #"Note that tee() has to keep copies of the values returned by the iterator; #in the worst case, it may need to keep all of them. #This should therefore be used carefully if the leading iterator can run #far ahead of the trailing iterator in a long stream of inputs. #If the separation is large, then you might as well use list() instead. #When the iterators track closely with one another, tee()" is ideal. Possible #applications include bookmarking, windowing, or lookahead iterators. #(Contributed by Raymond Hettinger.)" #obj.namespaces = {} new_prefixes = [] lead = None content = iter(obj.content) for subobj in content: if isinstance(subobj, NS): new_prefixes.append((subobj.prefix, subobj.namespace)) else: lead = subobj break prefix, local = splitqname(obj.qname) prefix = prefix or u'' if obj.ns == UNSPECIFIED_NAMESPACE: obj.ns = prefixes.get(prefix, u'') elif prefix not in prefixes or prefixes[prefix] != obj.ns: new_prefixes.append((prefix, obj.ns or u'')) attrs = [a for a in obj.attributes.itervalues() ] if obj.attributes else () if new_prefixes: prefixes = prefixes.copy() prefixes.update(dict(new_prefixes)) self.printer.start_element(obj.ns, obj.qname, new_prefixes, attrs) if lead: self.feed(lead, prefixes) for subobj in content: self.feed(subobj, prefixes) self.printer.end_element(obj.ns, obj.qname) return if isinstance(obj, basestring): self.printer.text(U(obj)) return if isinstance(obj, tree.element): #Be smart about bindery nodes self.printer.text(unicode(obj)) return try: obj = iter(obj) except TypeError, e: if callable(obj): self.feed(obj(), prefixes) else: #Just try to make it text, i.e. punt self.feed(unicode(obj), prefixes)
def feed(self, obj, prefixes=None): """ Feed a structure to the writer. The structure is interpreted as XML and serialized. obj - XML node proxy structure (or iterator thereof), such as amara.writers.struct.ROOT (proxy for a root (entity) node) or amara.writers.struct.E (proxy for an element). See documentation for other proxy node classes """ prefixes = prefixes or {} if isinstance(obj, ROOT): self.printer.start_document() for subobj in obj.content: self.feed(subobj) self.printer.end_document() return if isinstance(obj, NS): return if isinstance(obj, RAW): #parse_frag returns an entity ent = parse_fragment(inputsource.text(obj.content)) from amara.writers._treevisitor import visitor v = visitor(printer=self.printer) for child in ent.xml_children: v.visit(child) return if isinstance(obj, E): #First attempt used tee. Seems we ran into the warning at #http://www.python.org/doc/2.4.3/whatsnew/node13.html #"Note that tee() has to keep copies of the values returned by the iterator; #in the worst case, it may need to keep all of them. #This should therefore be used carefully if the leading iterator can run #far ahead of the trailing iterator in a long stream of inputs. #If the separation is large, then you might as well use list() instead. #When the iterators track closely with one another, tee()" is ideal. Possible #applications include bookmarking, windowing, or lookahead iterators. #(Contributed by Raymond Hettinger.)" #obj.namespaces = {} new_prefixes = [] lead = None content = iter(obj.content) for subobj in content: if isinstance(subobj, NS): new_prefixes.append((subobj.prefix, subobj.namespace)) else: lead = subobj break prefix, local = splitqname(obj.qname) prefix = prefix or u'' if obj.ns == UNSPECIFIED_NAMESPACE: obj.ns = prefixes.get(prefix, u'') elif prefix not in prefixes or prefixes[prefix] != obj.ns: new_prefixes.append((prefix, obj.ns or u'')) attrs = [ a for a in obj.attributes.itervalues() ] if obj.attributes else () if new_prefixes: prefixes = prefixes.copy() prefixes.update(dict(new_prefixes)) self.printer.start_element(obj.ns, obj.qname, new_prefixes, attrs) if lead: self.feed(lead, prefixes) for subobj in content: self.feed(subobj, prefixes) self.printer.end_element(obj.ns, obj.qname) return if isinstance(obj, basestring): self.printer.text(U(obj)) return if isinstance(obj, tree.element): #Be smart about bindery nodes self.printer.text(unicode(obj)) return try: obj = iter(obj) except TypeError, e: if callable(obj): self.feed(obj(), prefixes) else: #Just try to make it text, i.e. punt self.feed(unicode(obj), prefixes)