Skip to content

A python module which provides an abstraction to lxml's XPath and XSLT functionality in a manner resembling django database models.

License

Notifications You must be signed in to change notification settings

theatlantic/django-xml

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

53 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

django-xml

Test Status

django-xml is a python module which provides an abstraction to lxml's XPath and XSLT functionality in a manner resembling django database models.

Note

  • Version 2.0 drops support for Django < 1.11
  • Version 2.0.1 drops support for Python 3.4
  • Version 3.0 adds support for Django>=2.2, drops support for Python < 3.7

Contents

Installation

To install the latest stable release of django-xml, use pip or easy_install

pip install django-xml
easy_install django-xml

For the latest development version, install from source with pip:

pip install -e git+git://github.com/theatlantic/django-xml#egg=django-xml

If the source is already checked out, install via setuptools:

python setup.py develop

Example

import math
from djxml import xmlmodels

class NumbersExample(xmlmodels.XmlModel):

    class Meta:
        extension_ns_uri = "urn:local:number-functions"
        namespaces = {"fn": extension_ns_uri,}

    all_numbers  = xmlmodels.XPathIntegerListField("//num")
    even_numbers = xmlmodels.XPathIntegerListField("//num[fn:is_even(.)]")
    sqrt_numbers = xmlmodels.XPathFloatListField("fn:sqrt(//num)")

    @xmlmodels.lxml_extension
    def is_even(self, context, number_nodes):
        numbers = [getattr(n, 'text', n) for n in number_nodes]
        return all([bool(int(num) % 2 == 0) for num in numbers])

    @xmlmodels.lxml_extension
    def sqrt(self, context, number_nodes):
        sqrts = []
        for number_node in number_nodes:
            number = getattr(number_node, 'text', number_node)
            sqrts.append(repr(math.sqrt(int(number))))
        return sqrts


def main():
    numbers_xml = u"""
    <numbers>
        <num>1</num>
        <num>2</num>
        <num>3</num>
        <num>4</num>
        <num>5</num>
        <num>6</num>
        <num>7</num>
    </numbers>"""

    example = NumbersExample.create_from_string(numbers_xml)

    print "all_numbers  = %r" % example.all_numbers
    print "even_numbers = %r" % example.even_numbers
    print "sqrt_numbers = [%s]" % ', '.join(['%.3f' % n for n in example.sqrt_numbers])
    # all_numbers  = [1, 2, 3, 4, 5, 6, 7]
    # even_numbers = [2, 4, 6]
    # sqrt_numbers = [1.000, 1.414, 1.732, 2.000, 2.236, 2.449, 2.646]

if __name__ == '__main__':
    main()

Advanced Example

An example of django-xml usage which includes XsltField and @lxml_extension methods can be found here.

XmlModel Meta options

Metadata for an XmlModel is passed as attributes of an internal class named Meta. Listed below are the options that can be set on the Meta class.

namespaces
Options.namespaces = {}

A dict of prefix / namespace URIs key-value pairs that is passed to lxml.etree.XPathEvaluator() for all XPath fields on the model.

parser_opts
Options.parser_opts = {}

A dict of keyword arguments to pass to lxml.etree.XMLParser()

extension_ns_uri
Options.extension_ns_uri

The default namespace URI to use for extension functions created using the @lxml_extension decorator.

@lxml_extension reference

def lxml_extension(method=None, ns_uri=None, name=None)

The @lxml_extension decorator is for registering model methods as lxml extensions which can be used in XPathFields and XsltFields. All keyword arguments to it are optional.

ns_uri

The namespace uri for the function. If used in an XPathField, this uri will need to be one of the values in the namespaces attribute of the XmlModel's internal Meta class. If used in an XSLT, the namespace will need to be defined in the xslt file or string.

Defaults to the value of the extension_ns_uri attribute of the XmlModel's internal Meta class, if defined. If neither the extension_ns_uri attribute of XmlModel.Meta is set, nor is the ns_uri keyword argument passed, an ExtensionNamespaceException will be thrown.

name

The name of the function to register. Defaults to the method's name.

XPathField options

The following arguments are available to all XPath field types. All but the first are optional.

xpath_query
XPathField.xpath_query

The XPath query string to perform on the document. Required.

required
XPathField.required = True

If True, a DoesNotExist exception will be thrown if no nodes match the XPath query for the field. Defaults to True.

extra_namespaces
XPathField.extra_namespaces

A dict of extra prefix/uri namespace pairs to pass to lxml.etree.XPathEvaluator().

extensions
XPathField.extensions

Extra extensions to pass on to lxml.etree.XSLT. See the lxml documentation for details on how to form the extensions keyword argument.

XPathSingleNodeField options

ignore_extra_nodes
XPathSingleNodeField.ignore_extra_nodes = False

If True return only the first node of the XPath evaluation result, even if it evaluates to more than one node. If False, accessing an xpath field which evaluates to more than one node will throw a MultipleObjectsExist exception Defaults to False.

To return the full list of nodes, Use an XPathListField

XsltField options

xslt_file, xslt_string
XsltField.xslt_file
XsltField.xslt_string

The first positional argument to XsltField is the path to an xslt file. Alternatively, the xslt can be passed as a string using the xslt_string keyword argument. It is required to specify one of these fields.

parser
XsltField.parser

An instance of lxml.etree.XMLParser to override the one created by the XmlModel class. To override parsing options for the entire class, use the parser_opts attribute of the XmlModel internal Meta class.

extensions
XsltField.extensions = {}

Extra extensions to pass on to the constructor of lxml.etree.XSLT. See the lxml documentation for details on how to form the extensions keyword argument.

XmlModel field reference

class XsltField(xslt_file=None, xslt_string=None, parser=None, extensions=None)

Field which abstracts the creation of lxml.etree.XSLT objects. This field's return type is a callable which accepts keyword arguments that are passed as parameters to the stylesheet.

class XPathField(xpath_query, required=False, extra_namespaces=None, extensions=None)

Base field for abstracting the retrieval of node results from the xpath evaluation of an xml etree.

class XPathField(xpath_query, required=False, extra_namespaces=None, extensions=None)

Base field for abstracting the retrieval of node results from the xpath evaluation of an xml etree.

class XPathListField(xpath_query, required=False, extra_namespaces=None, extensions=None)

Field which abstracts retrieving a list of nodes from the xpath evaluation of an xml etree.

class XPathSingleItemField(xpath_query, required=False, extra_namespaces=None,
                           extensions=None, ignore_extra_nodes=False)

Field which abstracts retrieving the first node result from the xpath evaluation of an xml etree.

class XPathTextField(XPathSingleNodeField)

Returns a unicode value when accessed.

class XPathIntegerField(XPathSingleNodeField)

Returns an int value when accessed.

class XPathFloatField(XPathSingleNodeField)

Returns a float value when accessed.

class XPathDateTimeField(XPathSingleNodeField)

Returns a datetime.datetime value when accessed.

class XPathTextListField(XPathListField)

Returns a list of unicode values when accessed.

class XPathIntegerListField(XPathListField)

Returns a list of int values when accessed.

class XPathFloatListField(XPathListField)

Returns a list of float values when accessed.

class XPathDateTimeListField(XPathListField)

Returns a list of datetime.datetime values when accessed.

About

A python module which provides an abstraction to lxml's XPath and XSLT functionality in a manner resembling django database models.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •