# XML node engine

This chapter is dedicated to the XML node engine (xne), a subpart of the standard xml processing module. The XML node engine is designed to manipulate the node tree as well as searching for nodes.

## Node tree operations

The class `XneTree` provides a single framework to operate on a node and its associated tree. Since a node always carries a sub-tree, this chapter will refer to it as the node tree.

### Creating a node tree

A node tree is created either from a node at construction or with the help of the `set-node` method.

# create a node tree at construction const tree (afnix:xml:XneTree root) # change the node tree tree:set-node node

Once a tree is created, various methods are provided to operate on the whole tree. The `depth` method returns the depth of the node tree. The `get-node` methods returns the the node associated with the tree.

# get the tree depth println (tree:depth)

### Namespace operations

The concept of namespace is an extension to the xml standard. Unlike other programming language, the concept of namespace is designed to establish a binding between a name and an uri. Such binding permits to establish a scope for tags without too much burden. In the xml namespace terminology, an expanded name is composed of a prefix and a local name. The basic operations provided at the tree level is the prefix cancellation and the tree prefix setting.

# clear the prefix for the whole tree tree:clear-prefix # set a prefix for the whole tree tree:set-prefix "afnix"

The `set-prefix` changes the prefix for the whole tree. It is not necessary to clear first the prefix.

### Attribute operations

Each node in the node tree can have its attribute list modified in a single operation. The first operation is to clear all attributes for all nodes. Although this operation might be useful, it should be carried with caution. The attributes can also cleared more selectively by using the tag name as a filter. For more complex operation, the `clear-attribute` method of the `XmlTag` is the definitive answer.

# clear all attributes tree:clear-attribute # clear all attributes by tag name tree:clear-attribute "p"

The `set-attribute` method sets an attribute to the whole tree. The first argument is the attribute name and the second is a literal value. For more selective operations, the `set-attribute` method can be also called at the tag level.

# clear all attributes tree:set-attribute "class" "text"

When it comes to set attributes, there is a special operation related to the "id" attribute. Such attribute is supposed to be unique for the whole tree. For this reason, the `generate-id` generates a unique id for each node and assign the id attribute. The attribute is unique at the time of the call. If the tree is modified, and in particular, if new node are added, the method must be called again to regenerate the node id.

# set a unique id for all nodes tree:generate-id

## Node location and searching

The node location is the ability to locate one or several nodes in a xml tree. A node is generally located by name, path or id. Once a node has been located, it can be processed. Note that the node locator operates operates almost exclusively with `XmlTag` node, although it might not be always the case.

### Node selection

The process of finding a child node is obtained with the help of the `XneCond` class combined with the `select` method of the `XneTree` Object. The `select` method traverses the whole tree and attempts to match a condition for each node. If the condition is evaluated successfully for a node, the node is added in the result vector. Note that the tree can be traversed entirely or with only the first layer of children.

# creating a condition node const xcnd (afnix:xml:XneCond) # create a tree with a root node const tree (afnix:xml:XneTree root) # select all nodes for that condition trans result (tree:select xcnd)

In the previous example, the condition object is empty. This means that there is no condition, and thus works for all nodes. This previous example will return all nodes in the tree.

### Node condition

The `XmlCond` class provides several method to add a conditions. The `add` method is the method of choice to add a condition. The method operates with a condition type and a literal. Note that the object can contain several conditions.

# creating a condition node const xcnd (afnix:xml:XneCond) # add a condition by name xcnd:add afnix:xml:xne:NAME "p"

In the previous example, a condition is designed to operate with a tag name. Upon a call to the `select` method with this condition, all nodes in the tree that have the tag name p will be selected.

# creating a condition node const xcnd (afnix:xml:XneCond) # add a condition by name xcnd:add afnix:xml:xne:NAME "p" # add an index condition xcnd:add afnix:xml:xne:INDEX 0

In the previous example, a condition is designed to operate with a tag name and index. Upon a call to the `select` method with this condition, all nodes in the tree that have the tag name p and those child index is 0 will be selected.

### Selection result

The node selection operates by default on the whole tree. The `select` method, when called with a second boolean argument can restrict the search to the child nodes.

# creating a condition node const xcnd (afnix:xml:XneCond) # create a tree with a root node const tree (afnix:xml:XneTree root) # select all nodes for that condition trans result (tree:select xcnd false)

The selection results is stored in a vector object. The node order corresponds to the tree order obtained with a depth first search approach.