Named Values

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>