Revision c2a5b930 ncclient/rpc/reply.py
b/ncclient/rpc/reply.py | ||
---|---|---|
16 | 16 |
|
17 | 17 |
from xml.etree import cElementTree as ET |
18 | 18 |
|
19 |
from ncclient.content import multiqualify as _
|
|
19 |
from ncclient.content import namespaced_find
|
|
20 | 20 |
from ncclient.content import unqualify as __ |
21 | 21 |
|
22 | 22 |
import logging |
... | ... | |
36 | 36 |
return self._raw |
37 | 37 |
|
38 | 38 |
def parse(self): |
39 |
if self._parsed: |
|
40 |
return |
|
41 |
|
|
39 |
if self._parsed: return |
|
42 | 40 |
root = self._root = ET.fromstring(self._raw) # <rpc-reply> element |
43 |
|
|
44 |
if __(root.tag) != 'rpc-reply': |
|
45 |
raise ValueError('Root element is not RPC reply') |
|
46 |
|
|
47 |
ok = False |
|
48 | 41 |
# per rfc 4741 an <ok/> tag is sent when there are no errors or warnings |
49 |
oktags = _('ok') |
|
50 |
for oktag in oktags: |
|
51 |
if root.find(oktag) is not None: |
|
52 |
logger.debug('parsed [%s]' % oktag) |
|
53 |
break |
|
54 |
else: |
|
55 |
# create RPCError objects from <rpc-error> elements |
|
56 |
errtags = _('rpc-error') |
|
57 |
for errtag in errtags: |
|
58 |
for err in root.getiterator(errtag): # a particular <rpc-error> |
|
59 |
logger.debug('parsed [%s]' % errtag) |
|
42 |
ok = namespaced_find(root, 'ok') |
|
43 |
if ok is not None: |
|
44 |
logger.debug('parsed [%s]' % ok.tag) |
|
45 |
else: # create RPCError objects from <rpc-error> elements |
|
46 |
error = namespaced_find(root, 'rpc-error') |
|
47 |
if error is not None: |
|
48 |
logger.debug('parsed [%s]' % error.tag) |
|
49 |
for err in root.getiterator(error.tag): |
|
50 |
# process a particular <rpc-error> |
|
60 | 51 |
d = {} |
61 | 52 |
for err_detail in err.getchildren(): # <error-type> etc.. |
62 | 53 |
tag = __(err_detail.tag) |
63 | 54 |
d[tag] = (err_detail.text.strip() if tag != 'error-info' |
64 | 55 |
else ET.tostring(err_detail, 'utf-8')) |
65 | 56 |
self._errors.append(RPCError(d)) |
66 |
if self._errors: |
|
67 |
break |
|
68 |
|
|
57 |
self._parsing_hook(root) |
|
69 | 58 |
self._parsed = True |
70 | 59 |
|
71 |
@property |
|
72 |
def content_xml(self): |
|
73 |
'<rpc-reply> subtree' |
|
74 |
if not self._parsed: self.parse() |
|
75 |
return ''.join([ET.tostring(ele) for ele in self._root.getchildren()]) |
|
60 |
def extract_subtree_xml(self): |
|
61 |
return ''.join([ET.tostring(ele) |
|
62 |
for ele in ET.fromstring(self.xml).getchildren()]) |
|
76 | 63 |
|
77 | 64 |
@property |
78 |
def content_element(self): |
|
79 |
if not self._parsed: self.parse() |
|
80 |
return self._root.getchildren() |
|
81 |
|
|
82 |
@property |
|
83 |
def root_xml(self): |
|
65 |
def xml(self): |
|
84 | 66 |
'<rpc-reply> as returned' |
85 | 67 |
return self._raw |
86 | 68 |
|
87 | 69 |
@property |
88 |
def root_element(self): |
|
89 |
if not self._parsed: self.parse() |
|
90 |
return self._root |
|
91 |
|
|
92 |
@property |
|
93 | 70 |
def ok(self): |
94 | 71 |
if not self._parsed: self.parse() |
95 | 72 |
return not self._errors # empty list => false |
Also available in: Unified diff