All the lpOD level 0 features are available through the level 1 API, so the applications can create, retrieve or delete any element. They can create, select, update or delete any attribute or sub-element in a previously retrieved element.
The API provides functions and methods.
Functions are mainly used as object constructors, in order to create new ODF
elements that could be later attached to a document. The name of an object
constructor is like odf_create_xxx()
where "xxx" is the object type.
These constructors return "free" ODF elements, i.e. elements which don't belong
yet to any document; these elements may be attached later through a document or
context based method. However, some very specific objects may be created "in
place", through set_xxx()
element specific methods that create the objects
and directly append them to the calling element.
Once created, an object may be changed through the set_text()
and
set_attribute()
level 0 methods; however, the level 1 features allow the
user to set the most used properties using a more friendly way.
The level 1 set_attribute()
method extends the level 0 one by allowing
the user, in some situations, to forget the ODF namespaces. Knowing that every
ODF attribute name belong to a namespace, if set_attribute()
is
called from an ODF element with an attribute name without namespace prefix, the
method transparently concatenates the given name to the namespace prefix of the
calling object. get_attribute()
use the same behaviour. As a consequence,
the prefix may be safely omitted with attributes whose namespace is the same as
the namespace of the target element. In addition, knowing that an XML attribute
name can't contain blank spaces, these methods automatically replace every
space by a dash. For example, assuming p
is a paragraph (which belongs to
the "text" namespace), the three instructions below (that return the style of
the given paragraph) are equivalent:
p.get_attribute('text:style-name') p.get_attribute('style-name') p.get_attribute('style name')
There is an exception regarding a particular attribute, which is the style name.
When get_attribute()
or set_attribute()
is called with an attribute
name without prefix and ending with "style", the namespace prefix is inserted as
usual, but in addition a "-name" string is silently appended. Knowing that
attributes like "xxx-style-name" are very frequently used, this feature provides
a "xxx style" shortcut. As a consequence, the following instruction does the
same as each one of the previous example:
p.get_attribute('style')
A get_attributes()
method is provided, that returns all the attributes of
the calling element (with their real ODF names) and their values as a array
of named items. The set_attributes()
method allows the user to change or
create several attributes a a time; it checks and transforms the given
attribute names in the same way as set_attribute()
.
Some ODF elements own a set_properties()
method, which could sound redundant
with set_attributes()
. However, set_properties()
may set element
properties that imply element-specific transformations or constructs, makes some
consistency checks, and allow the user to provide property names that aren't
directly translated in simple attributes using the same name transformation
rules as set_attributes()
. The same logic apply to get_properties()
,
when defined.
In the present specification, some element properties or attributes may be
named using multiple-word designations (ex: display name
, page layout
)
that include spaces or dashes. Knowing that such designations are not easy to
use as variable names in every programming language, spaces and dashes should
be replaced by underscore ("_") characters in the lpOD executable.
implementations.
Some ODF elements own boolean attributes whose legal values are the "true" and
"false" text strings. Knowing that, for most programming languages, such strings
are not the same as the true
and false
boolean values, lpOD provides
specialized methods for such attributes. The set_boolean_attribute()
method
makes sure that, if the provided attribute value is false
according to the
rules of the host language, the target attribute will be set to the "false"
string. In addition, whatever the rules of the host language, any "false",
"off" or "no" string value, and the 0 numeric value, are regarded as false
,
as well as an empty (but defined) string. On the other hand, if the value is
null (i.e. not defined), the attribute is deleted and not set to "false",
following the common rule. There is a symmetric get_boolean_attribute()
that returns a regular true
or false
programmatic value (depending on
the host language) according to the ODF "true" or "false" boolean value.
The following example, assuming p
is a paragraph or heading, sets to "false"
the text:restart-numbering
attribute:
p.set_boolean_attribute('restart numbering', 0);
Some methods are document-based, other are context-based, and other are element-specific.
A document-based method is a method that makes sense at the document level
only. As an example, insert_style()
is document-based knowing that a style
is always defined at the document level.
A context-based method is designed in order to allow the user to insert, search,
process or delete content elements either in the whole document body, or in a
particular branch in the content tree. For example insert_element()
is
context-based because it allows the insertion of an element in any context. Of
course, a context is always an ODF element, but context-based methods are
available whatever the element type (however, a context-based method can raise
an error, for example when it's used to execute an operation that is not legal
for the current context).
The level 1 insert_element()
method supports all the features of the level 0
version, but it accepts the additional parameters before
and after
,
whose value is an ODF element. The element to be inserted takes place
immediately after the reference element provided through the after
parameter (if set). Alternatively, the insertion will take place before any
element which is provided through the after
parameter. These parameters are
intended to hide the low level XML jargon, and they are, of course, optional and
mutually exclusive.
On the other hand, append_element()
always attaches an element after the
last child of the context element.
An element-specific method works with specific ODF elements only, according to
their particular role. For example set_header()
is provided with ODF master
pages, because a header is an extension of a page style element, while
set_background()
is available with objects where a background definition
makes sense (such as page layouts or paragraph styles). Remember that all the
generic methods available for any element are introduced in the lpOD "level0"
documentation chapter.
Any ODF element in the level 1 API inherits all the features of the underlying XML element.
Every ODF element comes with methods that directly return its parent, next sibling, previous sibling, and the list of its children. These methods (which are provided by the underlying XML API) are available whatever the element type.
Any element provides a clone
method, which creates a new instance of the
element with all its children; this instance is free and can be inserted later
in any place in the same document or in another document. An element may be
removed through a delete
method from its parent element; the deletion
removes the element itself and all its children.
Some elements are created without any predefined attachment, i.e. as a free
elements, by specific constructor functions whose name is like
odf_create_xxx()
, where xxx
is the kind of element to be created.
A free element can be inserted later at the right place. Other elements, whose
definition doesn't make sens out of a specific context, are directly created in
place, through context-based methods whose name is set_xxx()
. Beware, every
set_xxx()
method creates or replaces something in the calling element, but
some of them don't create new elements.
A get_document()
method, called from any element, allows the user to get
the odf_document
object to which it belongs. This method returns a null
value if, for any reason, the element doesn't belong to a document.
According to the ODF 1.1 specification, some elements may own an identifier
attribute (whose XML name is "text:id"). The lpOD API provides a generic
get_id()
element accessor, that returns the value of the identifier, if any,
or a null value otherwise. A set_id()
method allows the applications to
arbitrarily set or change this identifier with any ODF element. If set_id()
is used with a null value, the identifier is deleted if it exists (and nothing
is done otherwise). There is no automatic compliance check associated with
set_id()
, so the user is allowed to set non standard identifiers and/or
identifiers that will not be supported or preserved by ODF-compliant
applications. On the other hand, identifiers may prove useful in order to
retrieve elements whose XML position is unknown or changing. Anyway, it's always
possible to set a non-standard identifier for a given processing session and
remove it before writing the changed document in a persistent storage.
Any element is able to be serialized and exported as an XML, UTF8-encoded string. Symmetrically, an element can be created from an application- provided XML string. As a consequence, lpOD-based applications can remotely transmit or receive any kind of ODF content.
The level 1 API is not validating, so the user is responsible of the ODF compliance (the API doesn't automatically prevent the applications from inserting an element at the wrong place or to set non-ODF elements).
Any element can be retrieved according to its sequential position in a given
context or its text content (if defined), through methods like get_xxx()
where "xxx" is the element type (i.e. "paragraph", "heading", etc).
The get_xxx() methods allows a content
and a position
parameters.
For example:
element = context.get_xxx(position = p, content='xyz')
When both content
and position
are set, position
specifies the
selected element within the result set that matches the given content
.
If position
is not set, the selected element is the first element that
matches the given content
. Without parameter, the first xxx
element
is selected. Of course, a null value is returned (without error) if the context
doesn't contain any element matching the conditions.
It's possible to get the list of elements of a known type in the context, using
get_xxx_list()
.
Of course, the API doesn't provide a distinct get_xxx()
method for any
possible element in an ODF-compliant document. On the other hand the list of
these specialized methods is growing. However, there is a generic level 1
get_element()
that requires the ODF element type as a mandatory argument,
and allows the content
and position
optional parameters. Example:
element = context.get_element('text:user-field-get', content='xyz');
The example above returns the first "user field get" element whose text content includes a "xyz" substring.
The two lines above retrieve an element among the children of context element.
The first one selects the child element at the given p
position.
The given position is an integer; the first position is zero; negative positions
are counted back from the last (-1 is the last position).
The second instruction retrieves the first element whose text content matches a
given regex
regular expression. Knowing that the regexp could be matched by
more than one element, the same method is available in a list context.
Addtional retrieval methods are available according to the element type.
Every search method operates in context, knowing that the context could be the whole document as well as a particular element (section, table, etc).