At the bottom of the XML example code, the dm:list whose id is
people, is a
container iterator. Container iterators
generate a values object that contains the
value generated by each child iterator.
The values object keeps these value instances in a map, keyed by their name.
The name is set by the iterator that generates them. If an iterator has a
name, set with setName(), then it sets the name into each value
it generates.
An I/O attribute can look up a value by name in the map. It gets the map from its enclosing element. If it doesn't find a map there, then it looks in the element's parent, then in that parent, etc., until it finds a map that contains the named value.
Now let's go back to the container iterator, people. It's name
is person, and it sets that name into the values object it
generates. This values object contains two values, age and
name.
When people generates each next value, the element named
element is listening. One action it takes is to set the value
into itself. The value contains the values object named person.
Because it sets this values object into itself, the map in
person is available for all of element's
attributes.
One attribute looks up the age value with the name person.age.
This amounts to finding the values object named person, then
looking in its map for a value named age.
person also has a value named name. This value is
itself a values object, that contains two value objects: first
and last. element's attributes are able to locate
these values with the names person.name.first and
person.name.last.
Attributes look up values when the attributes are formatted. This happens
during a write, which is the second action element takes when
it handles a next event from people.
Here is the configuration:
<?xml version="1.0" encoding="UTF-8"?>
<dm:application xmlns:dm="http://datamixer.org/config"
xmlns:dmio="http://datamixer.org/config/io">
<!-- output element -->
<dmio:element id="element" name="person">
<dmio:stream-writer/>
<dmio:xml-format/>
<dmio:attribute name="age" value="person.age"/>
<dmio:element name="name">
<dmio:attribute name="first" value="person.name.first"/>
<dmio:attribute name="last" value="person.name.last"/>
</dmio:element>
</dmio:element>
<!-- age -->
<dm:ints range="[1,100]">
<dm:iterator id="age" random="true"/>
</dm:ints>
<!-- first names -->
<dm:strings>
Alba, Belinda, Carl, Darrell, Herbert, Iva, Meghan, Minnie, Tammy, William
<dm:iterator id="first" name="first" repeat="true" random="true" replace="false"/>
</dm:strings>
<!-- last names -->
<dm:strings>
Beck, Cramer, Hamlin, Hancock, Hubbard, Hutchins, Oliver, Pickett, Quintero
<dm:iterator id="last" name="last" repeat="true" random="true" replace="false"/>
</dm:strings>
<!-- names -->
<dm:list id="names" name="name">
<dm:iterator reference="first"/>
<dm:iterator reference="last"/>
</dm:list>
<!-- people -->
<dm:list id="people" name="person">
<dm:iterator reference="age" name="age"/>
<dm:iterator reference="names"/>
<dm:listener listener="element" event="next" action="setValueWrite"/>
</dm:list>
</dm:application>
Here is the Java:
DatamixerContext context = root.getContext ();
DMElement element = context.getElement ("element");
DatamixerIterator iter = context.getDatamixerIterator ("people");
for (int i = 0; i < 5; i++)
iter.next ();
element.getWriter().flush ();
And here are the results:
<person age="53">
<name first="Herbert" last="Quintero"/>
</person>
<person age="21">
<name first="Belinda" last="Cramer"/>
</person>
<person age="91">
<name first="Meghan" last="Oliver"/>
</person>
<person age="17">
<name first="Iva" last="Pickett"/>
</person>
<person age="38">
<name first="Tammy" last="Hancock"/>
</person>