Data Nodes - Data Values vs. Data Groups

| No Comments

I am regularly asked about the following error message:

The SOM expression '$record.xxxxxx.xxxxxx' for the dataRef specified on field 'x', resolved to an incompatible node type of 'dataValue'.


This is a relatively easy problem to solve once you understand what the message is saying.  It's usually caused by binding an empty XML element in the data stream to a subform or binding an XML element containing mixed content to a field (although the message changes to "incompatible node type of 'dataGroup'" in the latter case).

As outlined in the XFA Specification, the XFA Data DOM is an abstraction of various different types of incoming data, the most common of which is XML.  The XFA Data DOM's "abstraction" is a very simple model that can colloquially be expressed as consisting of "things" and "groups of things".  Of course, in order to sound important, we gave them more technical sounding names.  Each object in the XFA Data DOM tree is called a Data Node.  Each Data Node can be one of two types: Data Values or Data Groups.  Data Values are name/value pairs (i.e. "things") and Data Groups are named groupings containing Data Values and/or subordinate Data Groups (i.e. "groups of things").  This is a fairly commonplace tree structure (i.e. Data Groups == branches and Data Values == leaves).  All data that is read into the Data DOM is interpreted as one of those two types of nodes.  Within an XFA Template, subforms can bind to Data Groups and fields can bind to Data Values but not vice versa.  You get the error above when subform is binding to a Data Value or a field is binding to a Data Group.

So since an XFA Data DOM only consists of Data Groups and Data Values, how does the XFA Data DOM map an incoming XML file into one of these two entities?  Well it turns out to be pretty self-evident.  If an XML element contains nothing but text, the XFA Data DOM assumes it's a Data Value.  If an XML element contains nothing but other XML elements, then it must be a Data Group.  This probably covers 99% of the XML that an XFA Data DOM has to map, so this algorithm works pretty well, however there are a couple of special cases.  The two special cases are: i) an empty XML element and ii) an XML element that contains both text and other XML elements (a.k.a. mixed content).

These two special cases don't fall into either of the two self-evident approaches.  An empty XML element could be a Data Value with no content or it could be a Data Group with no subordinate Data Groups or Data Values.  There's no way for the XFA Data DOM mapping code to know so, by default, the XFA Data DOM mapping code just picks one - in this case, it designates an XML element to represent a Data Value if that element is empty and it designates it a Data Group if that XML element contains mixed content (and while it's at it, it also wraps the textual content in one or more Data Value nodes subordinate to that Data Group).

To override the default behaviours, you need to give the XFA Data DOM some extra instructions.  There are some Config DOM options that govern the default behaviours however the more common case is to annotate individual XML elements with information to tell the XFA Data DOM how to interpret a given XML element.  This is done using a special attribute in the XFA Data namespace called dataNode.   The XFA Data DOM recognizes these attributes and uses them in preference to its own implicit rules.

Here's an example of to illustrate:

<form1 xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
    <subform1 xfa:dataNode="dataGroup"/> <!- interpret this element as a Data Group so it can map to a subform -->
    <subform2 xfa:dataNode="dataGroup"/> <!- interpret this element as a Data Group so it can map to a subform -->
    <subform1 xfa:dataNode="dataGroup"> <!- explicit information isn't necessary here but it doesn't hurt either -->
        <field1a>Some Data</field1a>
    </subform1>
    <field2 xfa:dataNode="dataValue">Some <annot>marked up</annot> data.</field1> <!- interpret the field1 element as a Data Value so it can map to a field -->
</form1>


Note, the latter case of mapping a mixed content XML element to a field is pretty uncommon (I've never seen it in 5 years of working with LiveCycle) however the former case of wanting to interpret an empty element as a Data Group is very common.  Adding this explicit attribute to tell the XFA Data DOM how to interpret an empty element is good practice for both empty elements and for elements that might be empty if you expect to map them to a subform.

Leave a comment

About this Entry

This page contains a single entry by Rob McDougall published on January 29, 2009 6:05 PM.

Sending Rich Text to LiveCycle ES was the previous entry in this blog.

Using Source Code Control with LiveCycle is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.

Categories