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 |