DOM guide: Working with elements
Two classes provide methods for working with elements after you have loaded a COLLADA instance document into your application:
daeDatabase
provides access to elements within a document.daeElement
is the base class for all COLLADA Object Model classes. This class uses the Reflective Object System (ROS) to provide considerable functionality without the need to use the generated subclass.
Querying Database Elements
The current version of the COLLADA DOM provides two methods to query the database to get information about specific elements:
daeDatabase::getElementCount
daeDatabase::getElement
- Note:
domConstants.h
provides constants for the element tag names (COLLADA_ELEMENT_*
) and the element types (COLLADA_TYPE_*
). When querying the database for elements based on type, always use theCOLLADA_TYPE_*
constant.
getElementCount
getElementCount
returns the number of elements for a particular query. For example, the following code asks how many <image> elements are in the database:
imageCount = collada_dom->getDatabase()->getElementCount(NULL, COLLADA_TYPE_IMAGE, NULL);
The additional parameters to getElementCount
make the request more specific. The first parameter represents the ID of the element. The third parameter represents the name of the document, and might be used if you have loaded elements from multiple instance documents.
getElement
getElement
requests that the database return a specific element. For example, the
following code returns an <image> element with an index that matches the value in el_number.
domImage *thisImage; daeInt error = collada_dom->getDatabase()->getElement((daeElement**)&thisImage, el_number, NULL, COLLADA_TYPE_IMAGE, NULL);
The element itself is returned in the first parameter. The third parameter restricts the query to a specific element by ID, and the fifth parameter restricts the search to a specific document.
Technique for querying elements
Typically, getElementCount
and getElement
are used as a pair, first getting the number of elements that match a particular ID, type, or document query, and then iterating through those by using the getElement
method. For example, if you want to take an action on all of the images in the database, you could do the following:
imageCount = collada_dom->getDatabase()->getElementCount(NULL, COLLADA_TYPE_IMAGE, NULL); for (unsigned int i=0; i<imageCount; i++) { error = collada_dom->getDatabase()->getElement((daeElement**)&thisImage, i, NULL, COLLADA_TYPE_IMAGE, NULL); /* take action on this image */ }
As another example, to take action on all images with the ID “landImage”, you could do the following:
imageCount = collada_dom->getDatabase()->getElementCount("landImage", COLLADA_TYPE_IMAGE, NULL); for (unsigned int i=0; i<imageCount; i++) { error = collada_dom->getDatabase()->getElement((daeElement**)&thisImage, i, "landImage", COLLADA_TYPE_IMAGE, NULL); /* take action on this land image */ }
The index passed to getElement
is not directly associated with the element within the database. The index relates to the query itself. The queries used for getElementCount
and getElement
must match in order for the index to be valid when passed to the getElement
method.
Determining an Element's Type
There are three approaches to determining the type of a daeElement
:
- Using the
daeElement::getElementType
method, which returns an enumerated value respresenting the element's type. The values returned by this function are in thedom/domTypes.h
header. This is the easiest approach.
- Using the
daeElement::getTypeName
method, which returns adaeString
containing the type name. To determine the type, compare this string with the matchingCOLLADA_TYPE_*
constant defined indom/domConstants.h
.
- By comparing the
daeElement::_meta
variable. The_meta
is a pointer to adaeMetaElement
, which is the class that contains all the ROS information for an element type. By doing a pointer comparison ondaeElement::getMeta
and the generated class's staticdom*::_Meta
, it is possible to find the element type. This is the approach that thedaeSafeCast
method uses to ensure type safety. (See also: DOM meta system.)
NOTE: The daeSafeCast
and daeElement::getElementType
approaches are newer additions to the COLLADA DOM. When looking at older source code using the DOM, expect to see the older methods used frequently for type checking.
Determining an Element's Name
Use the daeElement:getElementName
method to retrieve the name of an element. The element name is the XML tag that would be present in a COLLADA instance document.
For the majority of elements in the COLLADA DOM, getElementName
returns NULL, indicating that the element's name is the same as its type name, available from daeElement::getTypeName
.
Accessing Element Data
The easiest way to access element data is to cast the daeElement
to its strongly typed subclass. However, at times, it might not be possible to do the cast or it might be more convenient not to cast. The daeElement
class provides methods to access and manipulate data directly for such situations.
daeElement
provides the following methods for accessing various information about an element:
getDocument
provides access to the COLLADA document that the element belongs to.
getDocumentURI
is a helper method if you need only the document's name.
getParentElement
returns the parent element, which allows you to traverse up the tree to the root. If this method returns NULL, the element is the root of the tree. If the root element belongs to a document (getDocument
orgetDocumentURI
are non-NULL) then it is safe to assume that the element is adomCOLLADA
element, which is an element that is the root of a COLLADA document.
getChildren
populates an array with the children of an element. This allows you to iterate over all the children of an element and traverse down the element hierarchy. This array is ordered the same as it would be if the element were written to a COLLADA instance document. This array is the same as the_contents
array, if an element's dom* subclass has a_contents
array.
Accessing Attributes
The daeElement
class provides many functions for accessing the attributes that an element may have:
setAttribute
takes both the attribute name and the new value as string arguments. The COLLADA DOM converts the value from a string to the data type of the attribute. This method returns false if the element does not have an attribute with the specified name.hasAttribute
queries the existence of an attribute.isAttributeSet
returns true if the attribute exists and has been set. The attribute can be set when loading the document or programmatically. Attributes with default values are always considered set.getAttributeValue
returns a byte pointer to the memory used to store the specified attribute. The client application is responsible for type casting this pointer to the appropriate type before using it. One common mistake occurs when dealing with string attributes. Remember that this function returns a pointer to the data and thatdaeString
is a pointer itself, therefore this function returns a pointer to a pointer for string attributes.
Accessing the Value
- The daeElement::hasValue method is used to query if an element has a value.
- The daeElement::getValuePointer method works the same as daeElement::getAttributeValue except that it returns a pointer to the value field.
Adding and Removing Elements
The daeElement
class provides methods for adding elements to, and removing them from, the Object Model. Using these methods ensures that the element bookkeeping information maintained by the COLLADA DOM is appropriately updated. For example, many DOM classes contain a _contents
array, which keeps the correct order of all the child elements of that DOM class so they can be written in the valid order. The DOM maintains the _contents
array automatically when you use these methods to create and delete child elements.
Note. We strongly advise againt manually updating the _contents
array as it is very error-prone.
Adding Elements
The method daeElement::createAndPlace
creates a new element as a child of the current element. It places the new element in the appropriate field of its parent element based on the className
parameter provided in the method invocation.
The following example demonstrates how to add a new light to an existing library of lights:
// Add a new light to the library domLight *newLight = daeSafeCast<domLight>(myLib->createAndPlace(COLLADA_ELEMENT_LIGHT)); // Now you can add data to the new light.
- Note: The
daeElement::create*
methods work with element tag names, not element types. When using the string constants provided indomConstants.h
, use theCOLLADA_ELEMENT_*
value and not theCOLLADA_TYPE_*
. This is in contrast to working with the database, which uses element types.
Removing Elements
To remove a child element from its parent element, you can use either of the following methods; the results are identical, but one might better suit your coding style:
daeElement::removeChildElement
daeElement::removeFromParent
, which is a static method that finds the parent object automatically.
The following example demonstrates one way to remove a light from a library of lights:
daeElement* lightParent = myLight->getParentElement(); // Remove the light daeBool removed = lightParent->removeChildElement(myLight);
Here is the other method:
// Remove the light from its parent daeBool removed = daeElement::removeFromParent(myLight);
Moving Elements
To move an element from one parent to another, use daeElement::placeElement
. placeElement
handles all the "bookkeeping" for you. The element passed to placeElement
is removed from its old location and inserted as a child to the element placeElement
was called on. If the new parent belongs to a different document, placeElement
updates all the document references and the runtime database.
placeElement
automatically inserts the new child in a valid location within the parent's content model. There may be many valid locations for the new child, but placeElement
inserts the child in the first one available. To insert the new child at a specific location, use the placeElementAt
, placeElementBefore
, or placeElementAfter
methods.
Copying Elements
To copy a DOM element, rather than using the assignment operator, use the daeElement::clone
method, which provides a deep copy operation. After the element is cloned, you need to resolve any URIs that have been copied, as clone
does not do that automatically.
The DOM type daeString
, used in many objects derived from the daeElement
class, is a C-style string and not a C++ string class. If you use the assignment operator to copy a daeString
, you can end up with a dangling pointer if the original string is deleted.
COLLADA DOM - Version 2.4 Historical Reference |
---|
List of main articles under the DOM portal. |
User Guide chapters: • Intro • Architecture • Setting up • Working with documents • Creating docs • Importing docs • Representing elements • Working with elements • Resolving URIs • Resolving SIDs • Using custom COLLADA data • Integration templates • Error handling Systems: • URI resolver • Meta • Load/save flow • Runtime database • Memory • StringRef • Code generator |