Revision 2acc860a ncclient/content.py

b/ncclient/content.py
14 14

  
15 15
import logging
16 16
from xml.etree import cElementTree as ElementTree
17
from cStringIO import StringIO
17 18

  
18 19
logger = logging.getLogger('ncclient.content')
19 20

  
20
BASE_NS = 'urn:ietf:params:xml:ns:netconf:base:1.0'
21
NOTIFICATION_NS = 'urn:ietf:params:xml:ns:netconf:notification:1.0'
22

  
23
def qualify(tag, ns=BASE_NS):
24
    return '{%s}%s' % (ns, tag)
25 21

  
22
def qualify(tag, ns=None):
23
    if ns is None:
24
        return tag
25
    else:
26
        return '{%s}%s' % (ns, tag)
26 27
_ = qualify
27 28

  
28
def make_hello(capabilities):
29
    return '<hello xmlns="%s">%s</hello>' % (BASE_NS, capabilities)
30

  
31
def make_rpc(id, op):
32
    return '<rpc message-id="%s" xmlns="%s">%s</rpc>' % (id, BASE_NS, op)
33

  
34
def parse_hello(raw):
35
    from capabilities import Capabilities
36
    id, capabilities = 0, Capabilities()
37
    root = ElementTree.fromstring(raw)
38
    if root.tag == _('hello'):
39
        for child in root.getchildren():
40
            if child.tag == _('session-id'):
41
                id = int(child.text)
42
            elif child.tag == _('capabilities'):
43
                for cap in child.getiterator(_('capability')):
44
                    capabilities.add(cap.text)
45
    return id, capabilities
46

  
47
def parse_message_root(raw):
48
    from cStringIO import StringIO
49
    fp = StringIO(raw)
50
    for event, element in ElementTree.iterparse(fp, events=('start',)):
51
        if element.tag == _('rpc'):
52
            return element.attrib['message-id']
53
        elif element.tag == _('notification', NOTIFICATION_NS):
54
            return 'notification'
29

  
30
class RootElementParser:
31
    
32
    '''Parse the root element of an XML document. The tag and namespace of
33
    recognized elements, and attributes of interest can be customized.
34
    
35
    RootElementParser does not parse any sub-elements.
36
    '''
37
    
38
    def __init__(self, recognize=[]):
39
        self._recognize = recognize
40
    
41
    def recognize(self, element):
42
        '''Specify an element that should be successfully parsed.
43
        
44
        element should be a string that represents a qualified name of the form
45
        *{namespace}tag*.
46
        '''
47
        self._recognize.append((element, attrs))
48
    
49
    def parse(self, raw):
50
        '''Parse the root element from a string representing an XML document.
51
        
52
        Returns a (tag, attributes) tuple. tag is a string representing
53
        the qualified name of the recognized element. attributes is a
54
        {'attr': value} dictionary.
55
        '''
56
        fp = StringIO(raw)
57
        for event, element in ElementTree.iterparse(fp, events=('start',)):
58
            for e in self._recognize:
59
                if element.tag == e:
60
                    return (element.tag, element.attrib)
61
            break
62
        return None
63

  
64

  
65
###########
66

  
67
class XMLBuilder:
68
    
69
    @staticmethod
70
    def _element(node):
71
        element = ElementTree.Element( _(node.get('tag'),
72
                                         node.get('namespace', None)),
73
                                      node.get('attributes', {}))
74
        if node.has_key('children'):
75
            for child in node['children']:
76
                element.append(_make_element(child))
55 77
        else:
56
            return None
78
            return element
79
    
80
    @staticmethod
81
    def _etree(tree_dict):
82
        return ElementTree.ElementTree(XMLBuilder._element(tree_dict))
83
    
84
    @staticmethod
85
    def to_xml(tree_dict, encoding='utf-8'):
86
        fp = StringIO()
87
        self._etree(tree_dict).write(fp, encoding)
88
        return fp.get_value()
89

  
90

  
91
### Hello exchange
92

  
93
class Hello:
94
    
95
    NS = 'urn:ietf:params:xml:ns:netconf:base:1.0'
96
    
97
    @staticmethod
98
    def build(capabilities, encoding='utf-8'):
99
        hello = ElementTree.Element(_('hello', Hello.NS))
100
        caps = ElementTree.Element('capabilities')
101
        for uri in capabilities:
102
            cap = ElementTree.Element('capability')
103
            cap.text = uri
104
            caps.append(cap)
105
        hello.append(caps)
106
        tree = ElementTree.ElementTree(hello)
107
        fp = StringIO()
108
        tree.write(fp, encoding)
109
        return fp.getvalue()
110
    
111
    @staticmethod
112
    def parse(raw):
113
        'Returns tuple of (session-id, ["capability_uri", ...])'
114
        id, capabilities = 0, []
115
        root = ElementTree.fromstring(raw)
116
        if root.tag == _('hello', Hello.NS):
117
            for child in root.getchildren():
118
                if child.tag == _('session-id', Hello.NS):
119
                    id = int(child.text)
120
                elif child.tag == _('capabilities', Hello.NS):
121
                    for cap in child.getiterator(_('capability', Hello.NS)):
122
                        capabilities.append(cap.text)
123
        return id, capabilities

Also available in: Unified diff