Statistics
| Branch: | Tag: | Revision:

root / ncclient / xml_.py @ 9667bcb2

History | View | Annotate | Download (4.1 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 57b5f922 Shikhar Bhushan
"""The :mod:`xml` module provides methods for creating XML documents, parsing
17 57b5f922 Shikhar Bhushan
XML, and converting between different XML representations. It uses
18 57b5f922 Shikhar Bhushan
:mod:`~xml.etree.ElementTree` internally.
19 a7cb58ce Shikhar Bhushan
"""
20 a7cb58ce Shikhar Bhushan
21 4de03d63 Shikhar Bhushan
from cStringIO import StringIO
22 94dd4342 Shikhar Bhushan
from xml.etree import cElementTree as ET
23 94dd4342 Shikhar Bhushan
24 ebf2bbc6 Shikhar Bhushan
from ncclient import NCClientError
25 ebf2bbc6 Shikhar Bhushan
26 9667bcb2 Shikhar Bhushan
class XMLError(NCClientError):
27 a14c36f9 Shikhar Bhushan
    pass
28 bf31e33e Shikhar Bhushan
29 65c6a607 Shikhar Bhushan
### Namespace-related
30 94dd4342 Shikhar Bhushan
31 57b5f922 Shikhar Bhushan
#: Base NETCONF namespace
32 dd225c7a Shikhar Bhushan
BASE_NS_1_0 = 'urn:ietf:params:xml:ns:netconf:base:1.0'
33 408abf6d Shikhar Bhushan
#: namespace for Tail-f data model
34 408abf6d Shikhar Bhushan
TAILF_AAA_1_1 = 'http://tail-f.com/ns/aaa/1.1'
35 57b5f922 Shikhar Bhushan
#: namespace for Tail-f data model
36 408abf6d Shikhar Bhushan
TAILF_EXECD_1_1 = 'http://tail-f.com/ns/execd/1.1'
37 57b5f922 Shikhar Bhushan
#: namespace for Cisco data model
38 dd225c7a Shikhar Bhushan
CISCO_CPI_1_0 = 'http://www.cisco.com/cpi_10/schema'
39 dd225c7a Shikhar Bhushan
#: namespace for Flowmon data model
40 dd225c7a Shikhar Bhushan
FLOWMON_1_0 = 'http://www.liberouter.org/ns/netopeer/flowmon/1.0'
41 94dd4342 Shikhar Bhushan
42 94dd4342 Shikhar Bhushan
try:
43 94dd4342 Shikhar Bhushan
    register_namespace = ET.register_namespace
44 94dd4342 Shikhar Bhushan
except AttributeError:
45 94dd4342 Shikhar Bhushan
    def register_namespace(prefix, uri):
46 94dd4342 Shikhar Bhushan
        from xml.etree import ElementTree
47 94dd4342 Shikhar Bhushan
        # cElementTree uses ElementTree's _namespace_map, so that's ok
48 94dd4342 Shikhar Bhushan
        ElementTree._namespace_map[uri] = prefix
49 94dd4342 Shikhar Bhushan
50 dd225c7a Shikhar Bhushan
prefix_map = {
51 dd225c7a Shikhar Bhushan
    BASE_NS_1_0: 'nc',
52 dd225c7a Shikhar Bhushan
    TAILF_AAA_1_1: 'aaa',
53 dd225c7a Shikhar Bhushan
    TAILF_EXECD_1_1: 'execd',
54 dd225c7a Shikhar Bhushan
    CISCO_CPI_1_0: 'cpi',
55 dd225c7a Shikhar Bhushan
    FLOWMON_1_0: 'fm',
56 dd225c7a Shikhar Bhushan
}
57 57b5f922 Shikhar Bhushan
58 dd225c7a Shikhar Bhushan
for (ns, pre) in prefix_map.items():
59 dd225c7a Shikhar Bhushan
    register_namespace(pre, ns)
60 94dd4342 Shikhar Bhushan
61 dd225c7a Shikhar Bhushan
qualify = lambda tag, ns=BASE_NS_1_0: tag if ns is None else '{%s}%s' % (ns, tag)
62 bf31e33e Shikhar Bhushan
63 9667bcb2 Shikhar Bhushan
#unqualify = lambda tag: tag[tag.rfind('}')+1:]
64 d771dffc Shikhar Bhushan
65 9667bcb2 Shikhar Bhushan
def to_xml(ele, encoding="UTF-8"):
66 9667bcb2 Shikhar Bhushan
    """Element -> XML
67 9667bcb2 Shikhar Bhushan
    
68 9667bcb2 Shikhar Bhushan
    :type spec: :class:`~xml.etree.ElementTree.Element`
69 9667bcb2 Shikhar Bhushan
    :arg encoding: character encoding
70 9667bcb2 Shikhar Bhushan
    :rtype: :obj:`string`
71 d771dffc Shikhar Bhushan
    """
72 9667bcb2 Shikhar Bhushan
    xml = ET.tostring(ele, encoding)
73 9667bcb2 Shikhar Bhushan
    return xml if xml.startswith('<?xml') else '<?xml version="1.0" encoding="%s"?>%s' % (encoding, xml)
74 9667bcb2 Shikhar Bhushan
75 9667bcb2 Shikhar Bhushan
def to_ele(x):
76 9667bcb2 Shikhar Bhushan
    """XML -> Element
77 9667bcb2 Shikhar Bhushan
    
78 9667bcb2 Shikhar Bhushan
    :type xml: :obj:`string`
79 9667bcb2 Shikhar Bhushan
    :rtype: :class:`~xml.etree.ElementTree.Element`
80 9667bcb2 Shikhar Bhushan
    """
81 9667bcb2 Shikhar Bhushan
    return x if iselement(x) else ET.fromstring(x)
82 9667bcb2 Shikhar Bhushan
83 9667bcb2 Shikhar Bhushan
iselement = ET.iselement
84 d771dffc Shikhar Bhushan
85 d771dffc Shikhar Bhushan
def parse_root(raw):
86 614a698d Shikhar Bhushan
    """Efficiently parses the root element of an XML document.
87 4f650d54 Shikhar Bhushan

88 216bb34c Shikhar Bhushan
    :arg raw: XML document
89 614a698d Shikhar Bhushan
    :type raw: string
90 614a698d Shikhar Bhushan
    :returns: a tuple of `(tag, attributes)`, where `tag` is the (qualified) name of the element and `attributes` is a dictionary of its attributes.
91 216bb34c Shikhar Bhushan
    :rtype: `tuple`
92 0cdb8b3c Shikhar Bhushan
    """
93 9667bcb2 Shikhar Bhushan
    fp = StringIO(raw)
94 d771dffc Shikhar Bhushan
    for event, element in ET.iterparse(fp, events=('start',)):
95 d771dffc Shikhar Bhushan
        return (element.tag, element.attrib)
96 d771dffc Shikhar Bhushan
97 9667bcb2 Shikhar Bhushan
def validated_element(x, tags=None, attrs=None):
98 57b5f922 Shikhar Bhushan
    """Checks if the root element meets the supplied criteria. Returns a
99 57b5f922 Shikhar Bhushan
    :class:`~xml.etree.ElementTree.Element` instance if so, otherwise raises
100 57b5f922 Shikhar Bhushan
    :exc:`ContentError`.
101 4f650d54 Shikhar Bhushan

102 9667bcb2 Shikhar Bhushan
    :arg tags: tag name or a sequence of allowable tag names
103 9667bcb2 Shikhar Bhushan
    :arg attrs: sequence of required attribute names, each item may be a list of allowable alternatives
104 614a698d Shikhar Bhushan
    :arg text: textual content to match
105 9667bcb2 Shikhar Bhushan
    :type rep: :class:`~xml.etree.ElementTree.Element`
106 0cdb8b3c Shikhar Bhushan
    """
107 9667bcb2 Shikhar Bhushan
    ele = to_ele(x)
108 0b7d3b31 Shikhar Bhushan
    if tags:
109 0b7d3b31 Shikhar Bhushan
        if isinstance(tags, basestring):
110 0b7d3b31 Shikhar Bhushan
            tags = [tags]
111 614a698d Shikhar Bhushan
        if ele.tag not in tags:
112 9667bcb2 Shikhar Bhushan
            raise XMLError("Element [%s] does not meet requirement" % ele.tag)
113 614a698d Shikhar Bhushan
    if attrs:
114 d771dffc Shikhar Bhushan
        for req in attrs:
115 614a698d Shikhar Bhushan
            if isinstance(req, basestring): req = [req]
116 614a698d Shikhar Bhushan
            for alt in req:
117 614a698d Shikhar Bhushan
                if alt in ele.attrib:
118 d771dffc Shikhar Bhushan
                    break
119 d771dffc Shikhar Bhushan
            else:
120 9667bcb2 Shikhar Bhushan
                raise XMLError("Element [%s] does not have required attributes" % ele.tag)
121 d771dffc Shikhar Bhushan
    return ele
122 9667bcb2 Shikhar Bhushan
123 9667bcb2 Shikhar Bhushan
def new_ele(tag, attrs={}, **extra):
124 9667bcb2 Shikhar Bhushan
    return ET.Element(tag, attrs, **extra)
125 9667bcb2 Shikhar Bhushan
126 9667bcb2 Shikhar Bhushan
def sub_ele(parent, tag, attrs={}, **extra):
127 9667bcb2 Shikhar Bhushan
    return ET.SubElement(parent, tag, attrs, **extra)