Nowadays, there are a lot of XML formatted files used for both configuration and other resources, and therefore having a method to work with them is must have.
XFiles is a Fabric extension that aims to provides a support for reading and writing XML files located on remote servers or in local filesystem.
Note
The current version does support only reading the XML files.
See Changelog to see the list of features per version.
Short introduction to the extension, covering the installation and usage of the module.
The extension is dependent on following solutions:
Install the module by using following steps:
Download and install Distribute:
curl -O http://python-distribute.org/distribute_setup.py
sudo python distribute_setup.py
Install fabric-contrib.xfiles -module and Fabric (if not yet installed) using easy_install or pip:
easy_install -U Fabric fabric-contrib.xfiles
OR:
pip install -U Fabric fabric-contrib.xfiles
Simple usage example
Create Fabric configuration file fabfile.py, for example with following contents:
from fabric.api import env, run
from fabric.contrib import xfiles
def test():
for elem in xfiles.query('~/document.xml', '/root/item[id=test*]'):
# List all the elements having the attribute 'id'
# and it with value 'test', or something that starts with it
print elem.text
In this example, it is expected you have XML -document in your home directory (on remotehost -server), for example:
<root>
<item id="foo">value1</item>
<item id="testing">value2</item>
<item id="test">value3</item>
</root>
To see the outcome, run the command:
fab --username hostaccount -H remotehost test
Unless you have SSH private key provided for the remotehost, it’ll prompt for the password. After successful login, the XML file is read and text from all /root/item -elements is listed.
Tip
If the host parameter is not provided, or it is localhost, no SSH connection is needed/created and the file path is expected to be found from local filesystem. For example, following query reads the XML from same directory where the fabfile.py is:
for elem in xfiles.query('test.xml', '/root/sub'):
print elem
The example above shows only a one way how to use the extension. This shows additional and more advanced examples.
Makes query to remote XML file and returns the matching entries back
XQuery -like selection for the elements/values in the XML document. Selection format:
path/to/elements # <-- matches to elements -element
/root/path/to/elements # <-- absolute selection example
path/to=value # <-- matches with 'to' element when having text 'value' in it
path/to=val* # <-- matches with 'to' element when having text starting with 'val'
path/to/elements[id] # <-- matches to all elements having 'id' attribute
path/to/elements[@id] # <-- same as above
path/to/elements[i?] # <-- matches to all attributes with 'i'+something
path/to/elements[i*] # <-- matches to all attributes with 'i'
path/to/elements[id=value] # <-- matches to all elements having 'id' attribute with value 'value'
path/to/elements[@id=value] # <-- same as above
path/to/elements[id=val*] # <-- matches to all elements having 'val'+something
path/to/elements[i?=val*] # <-- combination from above
path/to[i?=val*]=val* # <-- combination from all of the above
Note
Wildcard are not supported for paths - at least not yet. So, for example, following is not supported:
path/to/elem*
Example usage:
# fabfile.py
from fabric.contrib import xfiles
def mycommand():
for elem in xfiles.query('path/to/remotedoc.xml', 'items/item'):
print elem.text, elem.attrib
And to run fabfile:
fab mycommand
Prints the matching entries (whereas query() only returns elements)
# fabfile.py
from fabric.contrib import xfiles
def mycommand(rpath):
#Lists the elements of remote document.
xfiles.pprint(rpath, 'items/item[attr=value]')
And to run fabfile:
fab mycommand:document.xml
Validates the given XML document, based on provided schema (if at all):
New in version 0.2.
If none of these schema files are provided, the basic XML document parsing is done to ensure the validity of the document.
If the validation fails, the exception is thrown, hopefully with descriptive message why the validation did not pass. If fail_on_error is set False, the function returns False on failure. Otherwise True.
Example
from fabric.contrib import xfiles
def check():
#Checks the setup config validity
dtd = 'server-config.dtd'
xsd = 'config.xsd'
try:
xfiles.validate('/etc/appx/server.xml', dtd=dtd)
xfiles.validate('/etc/appx/application.xml', xmlschema=xsd)
except Exception as e:
print 'Validation FAILED: %s' % e
Note
Schema validations requires lxml module to be installed on local environment.
The source and issue management is hosted in Bitbucket mercurial repository: http://bitbucket.org/jmu/fabric-contrib/. With the addition of liberal MIT-license, the extension is free to use for both commercial and personal usage.
For the development, following additional modules are needed: