Statistics
| Branch: | Tag: | Revision:

root / ncclient / content.py @ 2acc860a

History | View | Annotate | Download (3.9 kB)

1
# Copyright 2009 Shikhar Bhushan
2
#
3
# Licensed under the Apache License, Version 2.0 (the "License");
4
# you may not use this file except in compliance with the License.
5
# You may obtain a copy of the License at
6
#
7
#    http://www.apache.org/licenses/LICENSE-2.0
8
#
9
# Unless required by applicable law or agreed to in writing, software
10
# distributed under the License is distributed on an "AS IS" BASIS,
11
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
# See the License for the specific language governing permissions and
13
# limitations under the License.
14

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

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

    
21

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

    
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))
77
        else:
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