Statistics
| Branch: | Tag: | Revision:

root / ncclient / xml_.py @ 0c55eea9

History | View | Annotate | Download (3.7 kB)

1 94dd4342 Shikhar Bhushan
# Copyright 2009 Shikhar Bhushan
2 94dd4342 Shikhar Bhushan
#
3 94dd4342 Shikhar Bhushan
# Licensed under the Apache License, Version 2.0 (the "License");
4 94dd4342 Shikhar Bhushan
# you may not use this file except in compliance with the License.
5 94dd4342 Shikhar Bhushan
# You may obtain a copy of the License at
6 94dd4342 Shikhar Bhushan
#
7 94dd4342 Shikhar Bhushan
#    http://www.apache.org/licenses/LICENSE-2.0
8 94dd4342 Shikhar Bhushan
#
9 94dd4342 Shikhar Bhushan
# Unless required by applicable law or agreed to in writing, software
10 94dd4342 Shikhar Bhushan
# distributed under the License is distributed on an "AS IS" BASIS,
11 94dd4342 Shikhar Bhushan
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 94dd4342 Shikhar Bhushan
# See the License for the specific language governing permissions and
13 94dd4342 Shikhar Bhushan
# limitations under the License.
14 94dd4342 Shikhar Bhushan
15 a7cb58ce Shikhar Bhushan
16 bfcf8aea Shikhar Bhushan
"Methods for creating, parsing, and dealing with XML and ElementTree objects."
17 a7cb58ce Shikhar Bhushan
18 4de03d63 Shikhar Bhushan
from cStringIO import StringIO
19 94dd4342 Shikhar Bhushan
from xml.etree import cElementTree as ET
20 94dd4342 Shikhar Bhushan
21 ebf2bbc6 Shikhar Bhushan
from ncclient import NCClientError
22 ebf2bbc6 Shikhar Bhushan
23 bfcf8aea Shikhar Bhushan
class XMLError(NCClientError): pass
24 bf31e33e Shikhar Bhushan
25 65c6a607 Shikhar Bhushan
### Namespace-related
26 94dd4342 Shikhar Bhushan
27 57b5f922 Shikhar Bhushan
#: Base NETCONF namespace
28 dd225c7a Shikhar Bhushan
BASE_NS_1_0 = 'urn:ietf:params:xml:ns:netconf:base:1.0'
29 dd8b8dd7 Shikhar Bhushan
#: Namespace for Tail-f core data model
30 408abf6d Shikhar Bhushan
TAILF_AAA_1_1 = 'http://tail-f.com/ns/aaa/1.1'
31 dd8b8dd7 Shikhar Bhushan
#: Namespace for Tail-f execd data model
32 408abf6d Shikhar Bhushan
TAILF_EXECD_1_1 = 'http://tail-f.com/ns/execd/1.1'
33 dd8b8dd7 Shikhar Bhushan
#: Namespace for Cisco data model
34 dd225c7a Shikhar Bhushan
CISCO_CPI_1_0 = 'http://www.cisco.com/cpi_10/schema'
35 dd8b8dd7 Shikhar Bhushan
#: Namespace for Flowmon data model
36 dd225c7a Shikhar Bhushan
FLOWMON_1_0 = 'http://www.liberouter.org/ns/netopeer/flowmon/1.0'
37 94dd4342 Shikhar Bhushan
38 94dd4342 Shikhar Bhushan
try:
39 94dd4342 Shikhar Bhushan
    register_namespace = ET.register_namespace
40 94dd4342 Shikhar Bhushan
except AttributeError:
41 94dd4342 Shikhar Bhushan
    def register_namespace(prefix, uri):
42 94dd4342 Shikhar Bhushan
        from xml.etree import ElementTree
43 94dd4342 Shikhar Bhushan
        # cElementTree uses ElementTree's _namespace_map, so that's ok
44 94dd4342 Shikhar Bhushan
        ElementTree._namespace_map[uri] = prefix
45 94dd4342 Shikhar Bhushan
46 dd225c7a Shikhar Bhushan
prefix_map = {
47 dd225c7a Shikhar Bhushan
    BASE_NS_1_0: 'nc',
48 dd225c7a Shikhar Bhushan
    TAILF_AAA_1_1: 'aaa',
49 dd225c7a Shikhar Bhushan
    TAILF_EXECD_1_1: 'execd',
50 dd225c7a Shikhar Bhushan
    CISCO_CPI_1_0: 'cpi',
51 dd225c7a Shikhar Bhushan
    FLOWMON_1_0: 'fm',
52 dd225c7a Shikhar Bhushan
}
53 57b5f922 Shikhar Bhushan
54 dd225c7a Shikhar Bhushan
for (ns, pre) in prefix_map.items():
55 dd225c7a Shikhar Bhushan
    register_namespace(pre, ns)
56 94dd4342 Shikhar Bhushan
57 dd225c7a Shikhar Bhushan
qualify = lambda tag, ns=BASE_NS_1_0: tag if ns is None else '{%s}%s' % (ns, tag)
58 bf31e33e Shikhar Bhushan
59 9667bcb2 Shikhar Bhushan
#unqualify = lambda tag: tag[tag.rfind('}')+1:]
60 d771dffc Shikhar Bhushan
61 9667bcb2 Shikhar Bhushan
def to_xml(ele, encoding="UTF-8"):
62 dd8b8dd7 Shikhar Bhushan
    """Convert an :class:`~xml.etree.ElementTree.Element` to XML.
63 9667bcb2 Shikhar Bhushan
    
64 dd8b8dd7 Shikhar Bhushan
    :arg ele: the :class:`~xml.etree.ElementTree.Element`
65 9667bcb2 Shikhar Bhushan
    :arg encoding: character encoding
66 9667bcb2 Shikhar Bhushan
    :rtype: :obj:`string`
67 d771dffc Shikhar Bhushan
    """
68 9667bcb2 Shikhar Bhushan
    xml = ET.tostring(ele, encoding)
69 9667bcb2 Shikhar Bhushan
    return xml if xml.startswith('<?xml') else '<?xml version="1.0" encoding="%s"?>%s' % (encoding, xml)
70 9667bcb2 Shikhar Bhushan
71 9667bcb2 Shikhar Bhushan
def to_ele(x):
72 dd8b8dd7 Shikhar Bhushan
    """Convert XML to :class:`~xml.etree.ElementTree.Element`.
73 9667bcb2 Shikhar Bhushan
    
74 9667bcb2 Shikhar Bhushan
    :type xml: :obj:`string`
75 9667bcb2 Shikhar Bhushan
    :rtype: :class:`~xml.etree.ElementTree.Element`
76 9667bcb2 Shikhar Bhushan
    """
77 9667bcb2 Shikhar Bhushan
    return x if iselement(x) else ET.fromstring(x)
78 9667bcb2 Shikhar Bhushan
79 9667bcb2 Shikhar Bhushan
iselement = ET.iselement
80 d771dffc Shikhar Bhushan
81 d771dffc Shikhar Bhushan
def parse_root(raw):
82 614a698d Shikhar Bhushan
    """Efficiently parses the root element of an XML document.
83 4f650d54 Shikhar Bhushan

84 216bb34c Shikhar Bhushan
    :arg raw: XML document
85 dd8b8dd7 Shikhar Bhushan
    :returns: a tuple of `(tag, attrib)`, where *tag* is the (qualified)
86 dd8b8dd7 Shikhar Bhushan
    name of the element and *attrib* is a dictionary of its attributes.
87 216bb34c Shikhar Bhushan
    :rtype: `tuple`
88 0cdb8b3c Shikhar Bhushan
    """
89 9667bcb2 Shikhar Bhushan
    fp = StringIO(raw)
90 d771dffc Shikhar Bhushan
    for event, element in ET.iterparse(fp, events=('start',)):
91 d771dffc Shikhar Bhushan
        return (element.tag, element.attrib)
92 d771dffc Shikhar Bhushan
93 9667bcb2 Shikhar Bhushan
def validated_element(x, tags=None, attrs=None):
94 bfcf8aea Shikhar Bhushan
    "Checks if the root element of an XML document or Element meets the supplied criteria."
95 9667bcb2 Shikhar Bhushan
    ele = to_ele(x)
96 0b7d3b31 Shikhar Bhushan
    if tags:
97 0b7d3b31 Shikhar Bhushan
        if isinstance(tags, basestring):
98 0b7d3b31 Shikhar Bhushan
            tags = [tags]
99 614a698d Shikhar Bhushan
        if ele.tag not in tags:
100 9667bcb2 Shikhar Bhushan
            raise XMLError("Element [%s] does not meet requirement" % ele.tag)
101 614a698d Shikhar Bhushan
    if attrs:
102 d771dffc Shikhar Bhushan
        for req in attrs:
103 614a698d Shikhar Bhushan
            if isinstance(req, basestring): req = [req]
104 614a698d Shikhar Bhushan
            for alt in req:
105 614a698d Shikhar Bhushan
                if alt in ele.attrib:
106 d771dffc Shikhar Bhushan
                    break
107 d771dffc Shikhar Bhushan
            else:
108 9667bcb2 Shikhar Bhushan
                raise XMLError("Element [%s] does not have required attributes" % ele.tag)
109 d771dffc Shikhar Bhushan
    return ele
110 9667bcb2 Shikhar Bhushan
111 9667bcb2 Shikhar Bhushan
112 bfcf8aea Shikhar Bhushan
new_ele = lambda tag, attrs={}, **extra: ET.Element(tag, attrs, **extra)
113 bfcf8aea Shikhar Bhushan
114 bfcf8aea Shikhar Bhushan
sub_ele = lambda parent, tag, attrs={}, **extra: ET.SubElement(parent, tag, attrs, **extra)