replaced Element.get_elements() with XmlNode.get_instance(). replaced Element.add_ele...
authorTony Mack <tmack@paris.CS.Princeton.EDU>
Thu, 17 Nov 2011 02:56:32 +0000 (21:56 -0500)
committerTony Mack <tmack@paris.CS.Princeton.EDU>
Thu, 17 Nov 2011 02:56:32 +0000 (21:56 -0500)
sfa/rspecs/elements/element.py
sfa/rspecs/elements/versions/pgv2Link.py
sfa/rspecs/elements/versions/pgv2Node.py
sfa/rspecs/elements/versions/pgv2Services.py
sfa/rspecs/elements/versions/pgv2SliverType.py
sfa/rspecs/elements/versions/sfav1Node.py
sfa/rspecs/elements/versions/sfav1Sliver.py
sfa/rspecs/versions/pgv2.py
sfa/rspecs/versions/sfav1.py
sfa/util/xml.py

index 5789a9c..a2febfc 100644 (file)
@@ -11,47 +11,9 @@ class Element(dict):
             if key in fields:
                 self[key] = fields[key] 
 
-    @staticmethod
-    def get_elements(xml, xpath, element_class=None, fields=None):
-        """
-        Search the specifed xml node for elements that match the 
-        specified xpath query. 
-        Returns a list of objects instanced by the specified element_class.
-        """
-        if not element_class:
-            element_class = Element
-        if not fields and hasattr(element_class, 'fields'):
-           fields = element_class.fields
-        elems = xml.xpath(xpath)
-        objs = []
-        for elem in elems:
-            if not fields:
-                obj = element_class(elem.attrib, elem)
-            else:
-                obj = element_class({}, elem)
-                for field in fields:
-                    if field in elem.attrib:
-                        obj[field] = elem.attrib[field]    
-            objs.append(obj)
-        return objs
-
-    @staticmethod
-    def add_elements(xml, name, objs, fields=None):
-        """
-        Adds a child node to the specified xml node based on
-        the specified name , element class and object.    
-        """
-        if not isinstance(objs, list):
-            objs = [objs]
-        elems = []
-        for obj in objs:
-            if not obj:
-                continue
-            if not fields:
-                fields = obj.keys()
-            elem = xml.add_element(name)
-            for field in fields:
-                if field in obj and obj[field]:
-                    elem.set(field, unicode(obj[field]))
-            elems.append(elem)
-        return elems
+    def __getattr__(self, attr):
+        if hasattr(self, attr):
+            return getattr(self, attr)
+        elif self.element is not None and hasattr(self.element, attr):
+            return getattr(self.element, attr)
+        raise AttributeError, "Element class has no attribute %s" % attr
index e496d16..65513d0 100644 (file)
@@ -9,14 +9,14 @@ class PGv2Link:
     @staticmethod
     def add_links(xml, links):
         for link in links:
-            link_elems = Element.add(xml, 'link', link, ['component_name', 'component_id', 'client_id'])
-            link_elem = link_elems[0]
+            
+            link_elem = xml.add_instance('link', link, ['component_name', 'component_id', 'client_id'])
             # set component manager element            
             if 'component_manager' in link and link['component_manager']:
                 cm_element = link_elem.add_element('component_manager', name=link['component_manager'])
             # set interface_ref elements
             for if_ref in [link['interface1'], link['interface2']]:
-                Element.add(link_elem, 'interface_ref', if_ref, Interface.fields)
+                link_elem.add_instance('interface_ref', if_ref, Interface.fields)
             # set property elements
             prop1 = link_elem.add_element('property', source_id = link['interface1']['component_id'],
                 dest_id = link['interface2']['component_id'], capacity=link['capacity'], 
@@ -55,7 +55,8 @@ class PGv2Link:
                         link[attrib] = prop[attrib]
                              
             # get interfaces
-            interfaces = Element.get(Interface, link_elem, './default:interface_ref | ./interface_ref')
+            iface_elems = link_elem.xpath('./default:interface_ref | ./interface_ref')
+            interfaces = [iface_elem.get_instance(Interface) for iface_elem in iface_elems]
             if len(interfaces) > 1:
                 link['interface1'] = interfaces[0]
                 link['interface2'] = interfaces[1] 
index 4836cab..eb0518f 100644 (file)
@@ -1,7 +1,6 @@
 from sfa.util.plxrn import PlXrn, xrn_to_hostname
 from sfa.util.xrn import Xrn
 from sfa.util.xml import XpathFilter
-from sfa.rspecs.elements.element import Element
 from sfa.rspecs.elements.node import Node
 from sfa.rspecs.elements.sliver import Sliver
 from sfa.rspecs.elements.location import Location
@@ -19,19 +18,21 @@ class PGv2Node:
         node_elems = []
         for node in nodes:
             node_fields = ['component_manager_id', 'component_id', 'client_id', 'sliver_id', 'exclusive']
-            elems = Element.add_elements(xml, 'node', node, node_fields)
-            node_elem = elems[0]
+            node_elem = xml.add_instance('node', node, node_fields)
             node_elems.append(node_elem)
             # set component name
             if node.get('component_id'):
                 component_name = xrn_to_hostname(node['component_id'])
                 node_elem.set('component_name', component_name)
-            # set hardware types 
-            Element.add_elements(node_elem, 'hardware_type', node.get('hardware_types', []), HardwareType.fields) 
-            # set location       
-            location_elems = Element.add_elements(node_elem, 'location', node.get('location', []), Location.fields)
+            # set hardware types
+            for hardware_type in node.get('hardware_types', []): 
+                node_elem.add_instance('hardware_type', hardware_type, HardwareType.fields)
+            # set location
+            if node.get('location'):
+                node_elem.add_instance('location', node['location'], Location.fields)       
             # set interfaces
-            interface_elems = Element.add_elements(node_elem, 'interface', node.get('interfaces', []), ['component_id', 'client_id', 'ipv4'])
+            for interface in  node.get('interfaces', []):
+                node_elem.add_instance('interface', interface, ['component_id', 'client_id', 'ipv4'])
             # set available element
             if node.get('boot_state', '').lower() == 'boot':
                 available_elem = node_elem.add_element('available', now='True')
@@ -72,17 +73,29 @@ class PGv2Node:
             nodes.append(node) 
             if 'component_id' in node_elem.attrib:
                 node['authority_id'] = Xrn(node_elem.attrib['component_id']).get_authority_urn()
+            
+            # get hardware types
+            hardware_type_elems = node_elem.xpath('./default:hardwate_type | ./hardware_type')
+            node['hardware_types'] = [hw_type.get_instnace(HardwareType) for hw_type in hardware_type_elems]
+            
+            # get location
+            location_elems = node_elem.xpath('./default:location | ./location')
+            locations = [location_elem.get_instance(Location) for location_elem in location_elems]
+            if len(locations) > 0:
+                node['location'] = locations[0]
 
-            node['hardware_types'] = Element.get_elements(node_elem, './default:hardwate_type | ./hardware_type', HardwareType)
-            location_elems = Element.get_elements(node_elem, './default:location | ./location', Location)
-            if len(location_elems) > 0:
-                node['location'] = location_elems[0]
-            node['interfaces'] = Element.get_elements(node_elem, './default:interface | ./interface', Interface)
+            # get interfaces
+            iface_elems = node_elem.xpath('./default:interface | ./interface')
+            node['interfaces'] = [iface_elem.get_instance(Interface) for iface_elem in iface_elems]
+
+            # get services
             node['services'] = PGv2Services.get_services(node_elem)
+            
+            # get slivers
             node['slivers'] = PGv2SliverType.get_slivers(node_elem)    
-            available_elem = Element.get_elements(node_elem, './default:available | ./available', fields=['now'])
-            if len(available_elem) > 0 and 'name' in available_elem[0]:
-                if available_elem[0].get('now', '').lower() == 'true': 
+            available_elems = node_elem.xpath('./default:available | ./available')
+            if len(available_elems) > 0 and 'name' in available_elems[0].attrib:
+                if available_elems[0].attrib.get('now', '').lower() == 'true': 
                     node['boot_state'] = 'boot'
                 else: 
                     node['boot_state'] = 'disabled' 
index 9eb1ed9..9fadc56 100644 (file)
@@ -8,21 +8,35 @@ class PGv2Services:
     def add_services(xml, services):
         if not services:
             return 
-
         for service in services:
             service_elem = xml.add_element('services')
-            Element.add_elements(service_elem, 'install', service.get('install', []), Install.fields) 
-            Element.add_elements(service_elem, 'execute', service.get('execute', []), Execute.fields) 
-            Element.add_elements(service_elem, 'login', service.get('login', []), Login.fields) 
+            child_elements = {'install': Install.fields,
+                              'execute': Execute.fields,
+                              'login': Login.fields}
+            for (name, fields) in child_elements.items():
+                objects = service.get(name)
+                if not objects: 
+                    continue
+                if isinstance(objects, basestring):
+                    service_elem.add_instance(name, objects, fields)
+                elif isinstance(objects, list):
+                    for obj in objects:
+                        service_elem.add_instance(name, obj, fields)
               
     @staticmethod
     def get_services(xml):
         services = []
         for services_elem in xml.xpath('./default:services | ./services'):
             service = Services(services_elem.attrib, services_elem)
-            service['install'] = Element.get_elements(service_elem, './default:install | ./install', Install)
-            service['execute'] = Element.get_elements(service_elem, './default:execute | ./execute', Execute)
-            service['login'] = Element.get_elements(service_elem, './default:login | ./login', Login)
+            # get install 
+            install_elems = xml.xpath('./default:install | ./install')
+            service['install'] = [install_elem.get_instance(Install) for install_elem in install_elems]
+            # get execute
+            execute_elems = xml.xpath('./default:execute | ./execute')
+            service['execute'] = [execute_elem.get_instance(Execute) for execute_elem in execute_elems]
+            # get login
+            login_elems = xml.xpath('./default:login | ./login')
+            service['login'] = [login_elem.get_instance(Login) for login_elem in login_elems]
             services.append(service)  
         return services
 
index c071532..4271d21 100644 (file)
@@ -10,7 +10,7 @@ class PGv2SliverType:
         if not isinstance(slivers, list):
             slivers = [slivers]
         for sliver in slivers: 
-            sliver_elem = Element.add_elements(xml, 'sliver_type', sliver, ['type', 'client_id'])
+            sliver_elem = xml.add_instance('sliver_type', sliver, ['type', 'client_id'])
             PGv2SliverType.add_sliver_attributes(sliver_elem, sliver.get('pl_tags', []))
     
     @staticmethod
index 9933ece..61f8056 100644 (file)
@@ -19,19 +19,19 @@ class SFAv1Node:
 
     @staticmethod
     def add_nodes(xml, nodes):
-        network_elems = Element.get_elements(xml, '//network', fields=['name'])
+        network_elems = xml.xpath('//network')
         if len(network_elems) > 0:
             network_elem = network_elems[0]
         elif len(nodes) > 0 and nodes[0].get('component_manager_id'):
-            network_urn = nodes[0]['component_manager_id']    
-            network_elems = Element.add_elements(xml, 'network', {'name': Xrn(network_urn).get_hrn()})
-            network_elem = network_elems[0]
+            network_urn = nodes[0]['component_manager_id']
+            network_elem = xml.add_element('network', name = Xrn(network_urn).get_hrn()[0])     
+        else:
+            network_elem = xml
 
         node_elems = []       
         for node in nodes:
             node_fields = ['component_manager_id', 'component_id', 'boot_state']
-            elems = Element.add_elements(network_elem, 'node', node, node_fields)
-            node_elem = elems[0]  
+            node_elem = network_elem.add_instance('node', node, node_fields)
             node_elems.append(node_elem)
 
             # determine network hrn
@@ -43,17 +43,20 @@ class SFAv1Node:
             if 'component_id' in node and node['component_id']:
                 component_name = xrn_to_hostname(node['component_id'])
                 node_elem.set('component_name', component_name)
-                hostname_tag = node_elem.add_element('hostname')
-                hostname_tag.set_text(component_name)
+                hostname_elem = node_elem.add_element('hostname')
+                hostname_elem.set_text(component_name)
 
             # set site id
             if 'authority_id' in node and node['authority_id']:
                 node_elem.set('site_id', node['authority_id'])
 
-            location_elems = Element.add_elements(node_elem, 'location',
-                                                  node.get('location', []), Location.fields)
-            interface_elems = Element.add_elements(node_elem, 'interface', 
-                                                   node.get('interfaces', []), ['component_id', 'client_id', 'ipv4'])
+            # add locaiton
+            location = node.get('location')
+            if location:
+                node_elem.add_instance('location', location, Location.fields)
+
+            for interface in node.get('interfaces', []):
+                node_elem.add_instance('interface', interface, ['component_id', 'client_id', 'ipv4']) 
             
             #if 'bw_unallocated' in node and node['bw_unallocated']:
             #    bw_unallocated = etree.SubElement(node_elem, 'bw_unallocated', units='kbps').text = str(int(node['bw_unallocated'])/1000)
@@ -95,21 +98,6 @@ class SFAv1Node:
         node_elems = xml.xpath(xpath)
         return SFAv1Node.get_node_objs(node_elems)
 
-    # xxx Thierry : an ugly hack to get the tests to pass again
-    # probably this needs to be trashed
-    # the original code returned the <sliver /> tag, 
-    # but we prefer the <node> father node instead as it already holds data
-    # initially this was to preserve the nodename...
-    # xxx I don't get the ' | //default:node/default:sliver' ...
-    @staticmethod
-    def get_nodes_with_slivers_thierry(xml):
-        # dropping the ''
-        xpath = '//node[count (sliver)>0]'
-        node_elems = xml.xpath(xpath)
-        #  we need to check/recompute the node data 
-        
-        return node_elems
-
     @staticmethod
     def get_nodes_with_slivers(xml):
         xpath = '//node[count(sliver)>0] | //default:node[count(default:sliver)>0]' 
@@ -124,16 +112,25 @@ class SFAv1Node:
             node = Node(node_elem.attrib, node_elem)
             if 'site_id' in node_elem.attrib:
                 node['authority_id'] = node_elem.attrib['site_id']
-            location_objs = Element.get_elements(node_elem, './default:location | ./location', Location)
-            if len(location_objs) > 0:
-                node['location'] = location_objs[0]
-            bwlimit_objs = Element.get_elements(node_elem, './default:bw_limit | ./bw_limit', BWlimit)
-            if len(bwlimit_objs) > 0:
-                node['bwlimit'] = bwlimit_objs[0]
-            node['interfaces'] = Element.get_elements(node_elem, './default:interface | ./interface', Interface)
+            # get location
+            location_elems = node_elem.xpath('./default:location | ./location')
+            locations = [loc_elem.get_instance(Location) for loc_elem in location_elems]  
+            if len(locations) > 0:
+                node['location'] = locations[0]
+            # get bwlimit
+            bwlimit_elems = node_elem.xpath('./default:bw_limit | ./bw_limit')
+            bwlimits = [bwlimit_elem.get_instance(BWlimit) for bwlimit_elem in bwlimit_elems]
+            if len(bwlimits) > 0:
+                node['bwlimit'] = bwlimits[0]
+            # get interfaces
+            iface_elems = node_elem.xpath('./default:interface | ./interface')
+            ifaces = [iface_elem.get_instance(Interface) for iface_elem in iface_elems]
+            node['interfaces'] = ifaces
+            # get services
             node['services'] = PGv2Services.get_services(node_elem) 
+            # get slivers
             node['slivers'] = SFAv1Sliver.get_slivers(node_elem)
-#thierry    node['tags'] =  SFAv1PLTag.get_pl_tags(node_elem, ignore=Node.fields.keys())
+            # get tags
             node['tags'] =  SFAv1PLTag.get_pl_tags(node_elem, ignore=Node.fields)
             nodes.append(node)
         return nodes            
index d0a7592..e8fc0b7 100644 (file)
@@ -12,7 +12,7 @@ class SFAv1Sliver:
         if not isinstance(slivers, list):
             slivers = [slivers]
         for sliver in slivers:
-            sliver_elem = Element.add_elements(xml, 'sliver', sliver, ['name'])[0]
+            sliver_elem = xml.add_instance('sliver', sliver, ['name'])
             SFAv1Sliver.add_sliver_attributes(sliver_elem, sliver.get('tags', []))
             if sliver.get('sliver_id'):
                 sliver_id_leaf = Xrn(sliver.get('sliver_id')).get_leaf()
index ceff971..60387dc 100644 (file)
@@ -1,6 +1,6 @@
 from copy import deepcopy
 from StringIO import StringIO
-from sfa.util.xrn import urn_to_sliver_id
+from sfa.util.xrn import Xrn, urn_to_sliver_id
 from sfa.util.plxrn import hostname_to_urn, xrn_to_hostname 
 from sfa.rspecs.baseversion import BaseVersion
 from sfa.rspecs.elements.versions.pgv2Link import PGv2Link
@@ -20,18 +20,16 @@ class PGv2(BaseVersion):
     namespaces = dict(extensions.items() + [('default', namespace)])
 
     # Networks    
-    def get_network(self):
-        network = None
-        nodes = self.xml.xpath('//default:node[@component_manager_id][1]', namespaces=self.namespaces)
-        if nodes:
-            network  = nodes[0].get('component_manager_id')
-        return network
-
     def get_networks(self):
-        networks = self.xml.xpath('//default:node[@component_manager_id]/@component_manager_id', namespaces=self.namespaces)
-        return set(networks)
+        networks = set()
+        nodes = self.xml.xpath('//default:node[@component_manager_id]', namespaces=self.namespaces)
+        for node in nodes: 
+            if 'component_manager_id' in node:
+                network_urn  = node.get('component_manager_id')
+                network_hrn = Xrn(network_urn).get_hrn()[0]
+                networks.add({'name': network_hrn})
+        return list(networks)
 
-    
     # Nodes
 
     def get_nodes(self, filter=None):
index 85aa86e..39a5348 100644 (file)
@@ -23,12 +23,16 @@ class SFAv1(BaseVersion):
 
     # Network 
     def get_networks(self):
-        return Element.get_elements(self.xml, '//network', Element)
+        network_elems = self.xml.xpath('//network')
+        networks = [network_elem.get_instance(fields=['name', 'slice']) for \
+                    network_elem in network_elems]
+        return networks    
+
 
     def add_network(self, network):
         network_tags = self.xml.xpath('//network[@name="%s"]' % network)
         if not network_tags:
-            network_tag = etree.SubElement(self.xml.root, 'network', name=network)
+            network_tag = self.xml.add_element('network', name=network)
         else:
             network_tag = network_tags[0]
         return network_tag
index bb298a3..d6fd196 100755 (executable)
@@ -3,6 +3,7 @@ from types import StringTypes
 from lxml import etree
 from StringIO import StringIO
 from sfa.util.faults import InvalidXML
+from sfa.rspecs.elements.element import Element
 
 class XpathFilter:
     @staticmethod
@@ -37,32 +38,64 @@ class XpathFilter:
                 xpath = '[' + xpath + ']'
         return xpath
 
-class XmlNode:
-    def __init__(self, node, namespaces):
-        self.node = node
-        self.text = node.text
+class XmlElement:
+    def __init__(self, element, namespaces):
+        self.element = element
+        self.text = element.text
         self.namespaces = namespaces
-        self.attrib = node.attrib
+        self.attrib = element.attrib
         
 
     def xpath(self, xpath, namespaces=None):
         if not namespaces:
             namespaces = self.namespaces 
-        elems = self.node.xpath(xpath, namespaces=namespaces)
-        return [XmlNode(elem, namespaces) for elem in elems]
+        elems = self.element.xpath(xpath, namespaces=namespaces)
+        return [XmlElement(elem, namespaces) for elem in elems]
     
     def add_element(self, tagname, **kwds):
-        element = etree.SubElement(self.node, tagname, **kwds)
-        return XmlNode(element, self.namespaces)
+        element = etree.SubElement(self.element, tagname, **kwds)
+        return XmlElement(element, self.namespaces)
 
     def append(self, elem):
-        if isinstance(elem, XmlNode):
-            self.node.append(elem.node)
+        if isinstance(elem, XmlElement):
+            self.element.append(elem.element)
         else:
-            self.node.append(elem)
+            self.element.append(elem)
 
     def getparent(self):
-        return XmlNode(self.node.getparent(), self.namespaces)
+        return XmlElement(self.element.getparent(), self.namespaces)
+
+    def get_instance(self, instance_class=None, fields=[]):
+        """
+        Returns an instance (dict) of this xml element. The instance
+        holds a reference this xml element.   
+        """
+        if not instance_class:
+            instance_class = Element
+        if not fields and hasattr(instance_class, 'fields'):
+            fields = instance_class.fields
+
+        if not fields:
+            instance = instance_class(self.attrib, self)
+        else:
+            instance = instance_class({}, self)
+            for field in fields:
+                if field in self.attrib:
+                   instance[field] = self.attrib[field]  
+        return instance             
+
+    def add_instance(self, name, instance, fields=[]):
+        """
+        Adds the specifed instance(s) as a child element of this xml 
+        element. 
+        """
+        if not fields and hasattr(instance, 'keys'):
+            fields = instance.keys()
+        elem = self.add_element(name)
+        for field in fields:
+            if field in instance and instance[field]:
+                elem.set(field, unicode(instance[field]))
+        return elem                  
 
     def remove_elements(self, name):
         """
@@ -72,36 +105,36 @@ class XmlNode:
         
         if not element_name.startswith('//'):
             element_name = '//' + element_name
-        elements = self.node.xpath('%s ' % name, namespaces=self.namespaces) 
+        elements = self.element.xpath('%s ' % name, namespaces=self.namespaces) 
         for element in elements:
             parent = element.getparent()
             parent.remove(element)
 
     def remove(self, element):
-        if isinstance(element, XmlNode):
-            self.node.remove(element.node)
+        if isinstance(element, XmlElement):
+            self.element.remove(element.element)
         else:
-            self.node.remove(element)
+            self.element.remove(element)
 
     def get(self, key, *args):
-        return self.node.get(key, *args)
+        return self.element.get(key, *args)
 
-    def items(self): return self.node.items()
+    def items(self): return self.element.items()
 
     def set(self, key, value):
-        self.node.set(key, value)
+        self.element.set(key, value)
     
     def set_text(self, text):
-        self.node.text = text
+        self.element.text = text
     
     def unset(self, key):
-        del self.node.attrib[key]
+        del self.element.attrib[key]
   
     def iterchildren(self):
-        return self.node.iterchildren()
+        return self.element.iterchildren()
      
     def toxml(self):
-        return etree.tostring(self.node, encoding='UTF-8', pretty_print=True)                    
+        return etree.tostring(self.element, encoding='UTF-8', pretty_print=True)                    
 
     def __str__(self):
         return self.toxml()
@@ -115,7 +148,7 @@ class XML:
         self.schema = None
         if isinstance(xml, basestring):
             self.parse_xml(xml)
-        if isinstance(xml, XmlNode):
+        if isinstance(xml, XmlElement):
             self.root = xml
             self.namespaces = xml.namespaces
         elif isinstance(xml, etree._ElementTree) or isinstance(xml, etree._Element):
@@ -147,7 +180,7 @@ class XML:
         else:
             self.namespaces['default'] = 'default' 
 
-        self.root = XmlNode(root, self.namespaces)
+        self.root = XmlElement(root, self.namespaces)
         # set schema 
         for key in self.root.attrib.keys():
             if key.endswith('schemaLocation'):
@@ -210,48 +243,43 @@ class XML:
             namespaces = self.namespaces
         return self.root.xpath(xpath, namespaces=namespaces)
 
-    def set(self, key, value, node=None):
-        if not node:
-            node = self.root 
-        return node.set(key, value)
+    def set(self, key, value, element=None):
+        if not element:
+            element = self.root 
+        return element.set(key, value)
 
-    def remove_attribute(self, name, node=None):
-        if not node:
-            node = self.root
-        node.remove_attribute(name) 
+    def remove_attribute(self, name, element=None):
+        if not element:
+            element = self.root
+        element.remove_attribute(name) 
         
-    def add_element(self, name, **kwds):
+    def add_element(self, *args, **kwds):
         """
         Wrapper around etree.SubElement(). Adds an element to 
         specified parent node. Adds element to root node is parent is 
         not specified. 
         """
-        parent = self.root
-        xmlnode = parent.add_element(name, *kwds)
-        return xmlnode
+        return self.root.add_element(*args, **kwds)
 
-    def remove_elements(self, name, node = None):
+    def remove_elements(self, name, element = None):
         """
         Removes all occurences of an element from the tree. Start at 
         specified root_node if specified, otherwise start at tree's root.   
         """
-        if not node:
-            node = self.root
+        if not element:
+            element = self.root
+
+        element.remove_elements(name)
 
-        node.remove_elements(name)
+    def add_instance(self, *args, **kwds):
+        return self.root.add_instance(*args, **kwds)
 
-    def attributes_list(self, elem):
-        # convert a list of attribute tags into list of tuples
-        # (tagnme, text_value)
-        opts = []
-        if elem is not None:
-            for e in elem:
-                opts.append((e.tag, str(e.text).strip()))
-        return opts
+    def get_instance(self, *args, **kwds):
+        return self.root.get_instnace(*args, **kwds)
 
     def get_element_attributes(self, elem=None, depth=0):
         if elem == None:
-            elem = self.root_node
+            elem = self.root
         if not hasattr(elem, 'attrib'):
             # this is probably not an element node with attribute. could be just and an
             # attribute, return it
@@ -283,7 +311,7 @@ class XML:
         return self.toxml()
 
     def toxml(self):
-        return etree.tostring(self.root.node, encoding='UTF-8', pretty_print=True)  
+        return etree.tostring(self.root.element, encoding='UTF-8', pretty_print=True)  
     
     # XXX smbaker, for record.load_from_string
     def todict(self, elem=None):