Back to index

nordugrid-arc-nox  1.1.0~rc6
Classes
arcom.xmltree Namespace Reference

Classes

class  XMLTree

Detailed Description

The XMLTree class provides a way to convert from XML to native python structures and vica versa.

Examples
--------

if you have an XMLNode:

>>> x = arc.XMLNode('<soap-env:Envelope xmlns:hash="urn:hash" \
xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" \
xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" \
xmlns:xsd="http://www.w3.org/2001/XMLSchema" \
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\
<soap-env:Body>\
<hash:get>\
<hash:IDs>\
<hash:ID>0</hash:ID>\
<hash:ID>1</hash:ID>\
<hash:ID>2</hash:ID>\
</hash:IDs>\
</hash:get>\
</soap-env:Body>\
</soap-env:Envelope>')

you can convert it to an XMLTree:

>>> t = XMLTree(x)
>>> t.get()
[('soap-env:Envelope',
  [('soap-env:Body',
      [('hash:get',
    [('hash:IDs',
            [('hash:ID', '0'), ('hash:ID', '1'), ('hash:ID', '2')])])])])]

you can specify a path:

>>> t.get('/soap-env:Envelope/soap-env:Body/hash:get')
[('hash:get', [('hash:IDs', [('hash:ID', '0'), ('hash:ID', '1'), ('hash:ID', '2')])])]

this is not an XPath, it is just a plain path
empty tagname matches to everything, so these are the same as the previous example:

>>> t.get('/soap-env:Envelope//hash:get')
[('hash:get', [('hash:IDs', [('hash:ID', '0'), ('hash:ID', '1'), ('hash:ID', '2')])])]

>>> t.get('///hash:get')
[('hash:get', [('hash:IDs', [('hash:ID', '0'), ('hash:ID', '1'), ('hash:ID', '2')])])]

there are some other query methods, e.g. get_value and get_values:

>>> t.get('/////hash:ID')
[('hash:ID', '0'), ('hash:ID', '1'), ('hash:ID', '2')]

>>> t.get_value('/////hash:ID')
'0'

>>> t.get_values('/////hash:ID')
['0', '1', '2']

if you have an XML with key-value pairs, e.g.:

>>> t = XMLTree(from_string = '<root><object><key1>value1</key1><key2>value2</key2></object>\
    <object><key1>value3</key1><key2>value4</key2></object></root>')
>>> t.get()
[('root',
  [('object', [('key1', 'value1'), ('key2', 'value2')]),
     ('object', [('key1', 'value3'), ('key2', 'value4')])])]

now you can use the get_dict and get_dicts methods:

>>> t.get('/root/object')
[('object', [('key1', 'value1'), ('key2', 'value2')]),
('object', [('key1', 'value3'), ('key2', 'value4')])]

>>> t.get_dict('/root/object')
{'key1': 'value1', 'key2': 'value2'}

>>> t.get_dicts('/root/object')
[{'key1': 'value1', 'key2': 'value2'}, {'key1': 'value3', 'key2': 'value4'}]

you can specify the needed keys, and rename them:

>>> t.get_dicts('/root/object', {'key1':'new name'})
[{'new name': 'value1'}, {'new name': 'value3'}]


you can specify default value with get_value:

>>> t.get_value('///key1','default value')
'value1'
>>> t.get_value('///key3','default value')
'default value'

you can add an XMLTree to an XMLNode with the add_to_node method:

>>> x = XMLNode('<start/>')
>>> x.GetXML()
'<start/>'
>>> t.get('/root/object')
[('object', [('key1', 'value1'), ('key2', 'value2')]),
 ('object', [('key1', 'value3'), ('key2', 'value4')])]
>>> t.add_to_node(x,'/root/object')
>>> x.GetXML()
'<start><object><key1>value1</key1><key2>value2</key2></object>\
    <object><key1>value3</key1><key2>value4</key2></object></start>'

you can create an XMLTree from the tree structure:

>>> t2 = XMLTree(from_tree = ('object', [('key1', 'value5'), ('key2', 'value6')]))
>>> t2.get()
[('object', [('key1', 'value5'), ('key2', 'value6')])]

or you can add a new subtree to an XMLTree:

>>> t2.add_tree(('key3','valuex'),'/object')
>>> t2.get()
[('object', [('key1', 'value5'), ('key2', 'value6'), ('key3', 'valuex')])]

this will actually add it to the first node which matches the path, e.g.:

>>> t.get('/root/object')
[('object', [('key1', 'value1'), ('key2', 'value2')]),
 ('object', [('key1', 'value3'), ('key2', 'value4')])]

>>> t.add_tree(('key3','valuex'),'/root/object')
>>> t.get()
[('root',
  [('object', [('key1', 'value1'), ('key2', 'value2'), ('key3', 'valuex')]),
     ('object', [('key1', 'value3'), ('key2', 'value4')])])]

you can create list of subtrees with the get_trees method:

>>> t.get_trees('/root/object')
[<hash.xmltree.XMLTree instance at 0x17a6300>,
 <hash.xmltree.XMLTree instance at 0x17a6558>]

the str() method gives a string representation of an XMLTree:

>>> [str(i) for i in t.get_trees('/root/object')]
 ["('object', [('key1', 'value1'), ('key2', 'value2'), ('key3', 'valuex')])",
  "('object', [('key1', 'value3'), ('key2', 'value4')])"]

finally, you can create complex XML structures easily with XMLTree:
(this example is from the 'get' method of the ahash.AHashService class,
the 'resp' is a list of (ID, object) pairs,
where 'object' is a list of (section, property, value) tuples)

# create the 'getResponse' node and its child called 'objects'
response_node = out.NewChild('hash:getResponse')
# create an XMLTree from the results
tree = XMLTree(from_tree = 
    ('hash:objects',
[('hash:object', # for each object
    [('hash:ID', ID),
    ('hash:lines',
        [('hash:line', # for each line in the object
            [('hash:section', section),
            ('hash:property', property),
            ('hash:value', value)]
        ) for (section, property, value) in lines]
    )]
) for (ID, lines) in resp]
    ))
print tree
# convert to tree to XML via adding it to the 'getResponse' node
tree.add_to_node(response_node)

this generates an XML like this:

<hash:getResponse>
    <hash:objects>
<hash:object>
    <hash:ID>0</hash:ID>
        <hash:lines>
            <hash:line>
                <hash:section>1</hash:section>
                <hash:property>2</hash:property>
                <hash:value>3</hash:value>
            </hash:line>
            <hash:line>
                <hash:section>a</hash:section>
                <hash:property>b</hash:property>
                <hash:value>c</hash:value>
            </hash:line>
            <hash:line>
                <hash:section>su</hash:section>
                <hash:property>bi</hash:property>
                <hash:value>du</hash:value>
        </hash:line>
    </hash:lines>
</hash:object>
    </hash:objects>
</hash:getResponse>