Revision 65c6a607 ncclient/content.py

b/ncclient/content.py
21 21
class ContentError(NCClientError):
22 22
    pass
23 23

  
24
### Namespace-related ###
24
### Namespace-related
25 25

  
26 26
BASE_NS = 'urn:ietf:params:xml:ns:netconf:base:1.0'
27 27
# and this is BASE_NS according to cisco devices...
......
38 38
# we'd like BASE_NS to be prefixed as "netconf"
39 39
register_namespace('netconf', BASE_NS)
40 40

  
41
qualify = lambda tag, ns=BASE_NS: '{%s}%s' % (ns, tag)
41
qualify = lambda tag, ns=BASE_NS: tag if ns is None else '{%s}%s' % (ns, tag)
42 42

  
43
# i would have written a def if lambdas weren't so much fun
44
multiqualify = lambda tag, nslist=(BASE_NS, CISCO_BS): [qualify(tag, ns)
45
                                                        for ns in nslist]
43
multiqualify = lambda tag, nslist=(BASE_NS, CISCO_BS): [qualify(tag, ns) for ns in nslist]
46 44

  
47 45
unqualify = lambda tag: tag[tag.rfind('}')+1:]
48 46

  
49
### XML with Python data structures
50

  
51
def to_element(spec):
52
    "TODO: docstring"
53
    if iselement(spec):
54
        return spec
55
    elif isinstance(spec, basestring):
56
        return ET.XML(spec)
57
    if not isinstance(spec, dict):
58
        raise ContentError("Invalid tree spec")
59
    if 'tag' in spec:
60
        ele = ET.Element(spec.get('tag'), spec.get('attributes', {}))
61
        ele.text = spec.get('text', '')
62
        ele.tail = spec.get('tail', '')
63
        subtree = spec.get('subtree', [])
64
        # might not be properly specified as list but may be dict
65
        if isinstance(subtree, dict):
66
            subtree = [subtree]
67
        for subele in subtree:
68
            ele.append(XMLConverter.build(subele))
69
        return ele
70
    elif 'comment' in spec:
71
        return ET.Comment(spec.get('comment'))
72
    else:
73
        raise ContentError('Invalid tree spec')
74

  
75
def from_xml(xml):
76
    return ET.fromstring(xml)
77

  
78
def to_xml(repr, encoding='utf-8'):
79
    "TODO: docstring"
80
    xml = ET.tostring(to_element(repr), encoding)
81
    # some etree versions don't include xml decl with utf-8
82
    # this is a problem with some devices
83
    return (xml if xml.startswith('<?xml')
84
            else '<?xml version="1.0" encoding="%s"?>%s' % (encoding, xml))
85

  
86

  
87
## Utility functions
47
### Other utility functions
88 48

  
89 49
iselement = ET.iselement
90 50

  
......
103 63
    return found
104 64

  
105 65
def parse_root(raw):
106
    '''Internal use.
107
    Parse the top-level element from XML string.
66
    '''Parse the top-level element from XML string.
108 67
    
109 68
    Returns a `(tag, attributes)` tuple, where `tag` is a string representing
110 69
    the qualified name of the root element and `attributes` is an
......
121 80
    if req_attrs is not None:
122 81
        pass # TODO
123 82
    return rep
83

  
84
### XML with Python data structures
85

  
86
dtree2ele = DictTree.Element
87
dtree2xml = DictTree.XML
88
ele2dtree = Element.DictTree
89
ele2xml = Element.XML
90
xml2dtree = XML.DictTree
91
xml2ele = XML.Element
92

  
93
class DictTree:
94

  
95
    @staticmethod
96
    def Element(spec):
97
        if iselement(spec):
98
            return spec
99
        elif isinstance(spec, basestring):
100
            return XML.Element(spec)
101
        if not isinstance(spec, dict):
102
            raise ContentError("Invalid tree spec")
103
        if 'tag' in spec:
104
            ele = ET.Element(spec.get('tag'), spec.get('attributes', {}))
105
            ele.text = spec.get('text', '')
106
            ele.tail = spec.get('tail', '')
107
            subtree = spec.get('subtree', [])
108
            # might not be properly specified as list but may be dict
109
            if isinstance(subtree, dict):
110
                subtree = [subtree]
111
            for subele in subtree:
112
                ele.append(DictTree.Element(subele))
113
            return ele
114
        elif 'comment' in spec:
115
            return ET.Comment(spec.get('comment'))
116
        else:
117
            raise ContentError('Invalid tree spec')
118
    
119
    @staticmethod
120
    def XML(spec):
121
        Element.XML(DictTree.Element(spec))
122

  
123
class Element:
124
    
125
    @staticmethod
126
    def DictTree(ele):
127
        return {
128
            'tag': ele.tag,
129
            'attributes': ele.attrib,
130
            'text': ele.text,
131
            'tail': ele.tail,
132
            'subtree': [ Element.DictTree(child) for child in root.getchildren() ]
133
        }
134
    
135
    @staticmethod
136
    def XML(ele, encoding='utf-8'):
137
        xml = ET.tostring(ele, encoding)
138
        return xml if xml.startswith('<?xml') else '<?xml version="1.0" encoding="%s"?>\n%s' % (encoding, xml)
139

  
140
class XML:
141
    
142
    @staticmethod
143
    def DictTree(ele):
144
        return Element.DictTree(Element.XML(ele))
145
    
146
    @staticmethod
147
    def Element(xml):
148
        return ET.fromstring(xml)

Also available in: Unified diff