Stefan Cameron on Forms
Building intelligent forms using Adobe LiveCycle Designer

Schema Metadata

My first tutorial on XML schemas explained how to connect your form to a schema however it did not show some of the Data View palette’s special features with respect to metadata in XML schemas.

Using metadata based on a combination of the XML Schema appInfo and Dublin Core title and description elements, you can influence how the Data Connection Wizard creates fields you drag and drop from the data connection tree into your form. You can also direct the Data View palette to show some of this information in the Schema Data Connection Tree that it displays.

To demonstrate these features, I have extended the original movie rental schema by adding metadata to its schema elements.

Element Descriptions

Sometimes a schema element’s purpose or use isn’t immediately clear based on its name and/or other properties. For example, just by seeing that the schema has a “customer.account” element wouldn’t necessarily tell you that this element should be empty for a new customer (since the system would generate a new account number upon submission of the customer’s first movie rental order). To clarify the use of this element, a description can be provided:

<xs:element name="account" type="xs:string" minOccurs="0">
    <xs:annotation>
        <xs:appinfo>
            <dc:description>
                Customer's account number (empty if it's a new customer).
            </dc:description>
        </xs:appinfo>
    </xs:annotation>
</xs:element>

Using the “Data View palette > Palette menu button > ‘Show Both’ command”, you can see the <dc:description> metadata associated with elements in your schema right within the Data Connection Tree:

Note that the description element must be part of the Dublin Core namespace (xmlns:dc=http://purl.org/dc/elements/1.1/) and must be contained within the XML Schema //annotation/appInfo elements in order for the Data Connection Wizard to detect it.

Form Object Captions

Often times schemas are defined at a corporate level because they can represent business rules and describe how data must be structured for its systems to be able to interpret it correctly. In those cases, it may be useful to also influence/dictate the labels that should be used to identify fields associated to certain schema elements. This can also be achieved with metadata by specifying title information:

<xs:element name="account" type="xs:string" minOccurs="0">
    <xs:annotation>
        <xs:appinfo>
            <dc:title>Account #:</dc:title>
        </xs:appinfo>
    </xs:annotation>
</xs:element>

Unlike descriptive metadata, this information is not displayed in the Data Connection Tree. Instead, it is used by the Data Connection Wizard when you drag and drop a schema element from the Data Connection Tree into your form.

Remember that, in the original schema (that didn’t have any metadata), generated fields would get captions similar to their schema element names. For example,  dragging the “customer.account” field into a form would produce a field with “Account” as its caption. With the title metadata as defined above, the generated caption would instead be “Account #:”, as in the image below:

Note that the title element must be part of the Dublin Core namespace (xmlns:dc=http://purl.org/dc/elements/1.1/) and must be contained within the XML Schema //annotation/appInfo elements in order for the Data Connection Wizard to detect it.

Extra Descriptive Information

There’s one more way to provide information related to an element in a schema: Any text that is directly specified within an XML Schema //annotation/appInfo element (and is not further contained within a Dublin Core title or description element) is interpreted as extra “descriptive information”. When the element is dragged and dropped into a form, this text will be imported and associated with the generated field within a <desc> node, provided the “Generate Descriptive Information” option is checked in the “Data View palette > Palette menu button > Options dialog”:

For example, the “returnBy” schema element is defined as follows:

<xs:element name="returnBy" type="xs:date">
    <xs:annotation>
        ...
        <xs:appinfo>
            Movies must be returned by 11:59pm on this date.
        </xs:appinfo>
        <xs:appinfo>
            The late fee is is $0.50/hour.
        </xs:appinfo>
    </xs:annotation>
</xs:element>

Dragging and dropping that element into your form would produce the following field mark-up in the XML Source view:

<field name="returnBy">
    ...
    <desc>
        <text name="Schema Annotation">
            Movies must be returned by 11:59pm on this date.
        </text>
        <text name="Schema Annotation 2">
            The late fee is is $0.50/hour.
        </text>
    </desc>
</field>

The Info palette could then be used to view the contents of all nodes inside the selected field’s <desc> node:

You can associate any number of extra “descriptive information” metadata elements to a single schema element definition. Each one would be imported as a separate <text name=”Schema Annotation {x}”> node within the associated form object’s <desc> node

This information can also be viewed within the Data View palette by choosing the “Palette menu button > ‘Show Info’ command”. This will display the Info Panel in the bottom half of the palette. Selecting the “returnBy” schema element would then display the following information:

  • XFA object name (returnBy);
  • associated XFA object type (date/time field, since the schema defines its type as “date”);
  • occurrence (single since it isn’t repeatable like the “movie” element, for example); and
  • all other metadata identified as “descriptive info” associated to the element.

Script Access

Finally, the descriptive information found in a form object’s //desc/text nodes can be retrieved via script by accessing its “desc” node property and iterating through all child nodes that are of type “text” and have “Schema Annotation” in their name.

For example, to output the two descriptions in the “returnBy” field (as defined above) to the JavaScript Console in Acrobat, you could use the following script:

// JavaScript:
var descList = returnBy.desc.nodes;
for (var i = 0; i < descList.length; i++)
{
    var item = descList.item(i);
    if (item.className == "text" && item.name &&
            item.name.indexOf("Schema Annotation") == 0)
    {
        console.println(item.value);
    }
}

With a little more effort, you could parse-out all sorts of useful information provided by this type of metadata in your schemas though, most of the time, that information can usually be expressed in real schema mark-up (e.g. list items and values).

Combinations

Of course, you aren’t limited to using a single type of metadata on a given schema element: You can combine them to provide the degree of information you require for any element. For example, the “customer.account” element specifies both title and description metadata while the “returnBy” element specifies title and descriptive information metadata.


Posted by Stefan Cameron on August 28th, 2009
Filed under Data Binding,Designer,Scripting,Tutorials,XFA
Both comments and pings are currently closed.

17 Responses to “Schema Metadata”

  1. duane on September 8th, 2009

    Hi Stefan,

    My question doesn’t directly relate to your post, but I have been looking everywhere for an answer with no luck.

    I have an xml schema which uses namespaces (included below). I have a form which uses a multi-selectListBox. I am attempting to bind the ListBox on the form to the schema, and I’m having all kinds of problems.

    If I bind the ListBox to

    $.BusinessName or $.BusinessName[*]

    Then the resulting XML data created by the form will look like this:

    ListBox Value 1
    ListBox Value 2

    The problem is that although the data from the does exist within the XML data, the node has been created without the doc: NameSpace prefix, and therefore it will not pass validation against the schema.

    If I bind the ListBox to $.BusinessName.value[*]

    Then I will get

    In this case, the proper NameSpace prefix and Attributes are created with the the node, however the data from the form is not in the XML data file – the node will always be empty.

    Could you please provide any information of how to bind a ListBox to a schema while preserving XML Namespaces – as Designer/Acrobat seems store ListBox selections by simply creating nodes which do not conform to the schema.

    Here is a scaled down version of the XSD which should work on it’s own.

    Thanks

    CCT
    String

    SC
    0..1

    SC
    0..1

  2. duane on September 8th, 2009

    Sorry – forgot to modify the xsd for posting:

    <?xml version=”1.0″?>
    <xsd:schema targetNamespace=”urn:xml-gov-au:vic:easybiz:draft:docs:MyApplication_0.1:0.1″ xmlns:doc=”urn:xml-gov-au:vic:easybiz:draft:docs:MyApplication_0.1:0.1″ xmlns:xsd=”http://www.w3.org/2001/XMLSchema” xmlns:ccts=”urn:un:unece:uncefact:documentation:standard:CoreComponentsTechnicalSpecification:2″ elementFormDefault=”qualified” attributeFormDefault=”unqualified” version=”0.1″>
    <xsd:element name=”Application” type=”doc:ApplicationType”/>
    <xsd:complexType name=”ApplicationType”>
    <xsd:sequence>
    <xsd:element name=”AssociatedBusinessName” minOccurs=”0″ maxOccurs=”unbounded”>
    <xsd:complexType>
    <xsd:sequence>
    <xsd:element name=”value” type=”doc:TextType” minOccurs=”0″ maxOccurs=”unbounded”/>
    </xsd:sequence>
    </xsd:complexType>
    </xsd:element>
    </xsd:sequence>
    </xsd:complexType>
    <xsd:complexType name=”TextType”>
    <xsd:annotation>
    <xsd:documentation xml:lang=”en”>
    <ccts:Acronym>CCT</ccts:Acronym>
    <ccts:PrimaryRepresentationTerm>String</ccts:PrimaryRepresentationTerm>
    </xsd:documentation>
    </xsd:annotation>
    <xsd:simpleContent>
    <xsd:extension base=”xsd:string”>
    <xsd:attribute name=”LanguageIdentifier” type=”xsd:string” use=”optional”>
    <xsd:annotation>
    <xsd:documentation xml:lang=”en”>
    <ccts:Acronym>SC</ccts:Acronym>
    <ccts:Cardinality>0..1</ccts:Cardinality>
    </xsd:documentation>
    </xsd:annotation>
    </xsd:attribute>
    <xsd:attribute name=”LanguageLocaleIdentifier” type=”xsd:string” use=”optional”>
    <xsd:annotation>
    <xsd:documentation xml:lang=”en”>
    <ccts:Acronym>SC</ccts:Acronym>
    <ccts:Cardinality>0..1</ccts:Cardinality>
    </xsd:documentation>
    </xsd:annotation>
    </xsd:attribute>
    </xsd:extension>
    </xsd:simpleContent>
    </xsd:complexType>
    </xsd:schema>

  3. duane on September 8th, 2009

    Repost – corrected to display script properly –

    My question doesn’t directly relate to your post, but I have been looking everywhere for an answer with no luck.

    I have an xml schema which uses namespaces (included below). I have a form which uses a multi-selectListBox. I am attempting to bind the ListBox on the form to the schema, and I’m having all kinds of problems.

    If I bind the ListBox to

    $.BusinessName or $.BusinessName[*]

    Then the resulting XML data created by the form will look like this:

    <doc:BusinessName>
    <value>ListBox Value 1</value>
    <value>ListBox Value 2</value>
    </doc:BusinessName>

    The problem is that although the data from the does exist within the XML data, the node has been created without the doc: NameSpace prefix, and therefore it will not pass validation against the schema.

    If I bind the ListBox to $.BusinessName.value[*]

    Then I will get

    <doc:BusinessName>
    <doc:value LanguageIdentifier=”” LanguageLocaleIdentifier=””/>ListBox Value 1</doc:value>
    <doc:value LanguageIdentifier=”” LanguageLocaleIdentifier=””/>ListBox Value 2</doc:value>
    </doc:BusinessName>

    In this case, the proper NameSpace prefix and Attributes are created with the the node, however the data from the form is not in the XML data file – the node will always be empty.

    Could you please provide any information of how to bind a ListBox to a schema while preserving XML Namespaces – as Designer/Acrobat seems store ListBox selections by simply creating nodes which do not conform to the schema.

    Here is a scaled down version of the XSD which should work on it’s own.

    Thanks

  4. duane on September 8th, 2009

    Wow – I’m having all kinds of issues posting properly today.

    The above should read:

    If I bind the ListBox to $.BusinessName.value[*]

    Then I will get

    <doc:BusinessName>
    <doc:value LanguageIdentifier=”” LanguageLocaleIdentifier=””/>
    </doc:BusinessName>

    In this case, the proper NameSpace prefix and Attributes are created with the the node, however the data from the form is not in the XML data file – the node will always be empty.

  5. flashscope on September 14th, 2009

    hey Stefan,
    great tutorial on metadata. thanks for sharing your experience.

  6. Sandeep Goli on September 16th, 2009

    Hello Stefan,

    I have a problem with one of my forms. I would like to send it over to you in an email to better describe the problem.
    Can i have your email id where i can forward the form?

    Thank you.

  7. Stefan Cameron on September 16th, 2009

    Sandeep Goli,

    I usually don’t do that unless there’s a real need because it can be very time-consuming however I can appreciate that it can make it easier to explain a problem while seeing the form first-hand. If you feel you can’t explain it here, then you can send it to formcollateral1 at stefcameron dot com. Please make sure you include all referenced material (schema, XML data, fragments, etc.) otherwise I won’t be able to load it in Designer…

  8. Bruce on September 16th, 2009

    Hi Stefan,

    This is a great post. Is this documented anywhere, I often feel like I’m missing a manual working with Designer.

    Thanks again.

  9. Stefan Cameron on September 17th, 2009

    duane,

    Your timing is perfect as I’m preparing a blog post on schemas and mutli-selection lists though I had not considered the namespace issue with the generated <value> nodes.

    I will investigate further and report back here when I get some answers.

  10. Stefan Cameron on September 17th, 2009

    Bruce,

    Thanks! I don’t know if this is officially documented anywhere. It may be buried somewhere deep inside the XFA spec but I’m not sure.

  11. Stefan Cameron on September 23rd, 2009

    duane,

    I asked some of my colleagues for help on this one and was able to find a workaround with John Brinkman‘s help.

    When a multi-selection is made in a list, its rawValue property stores the multi-selection as a new line (\n)-delimited list of strings (in the Form DOM). This value then gets stored in the Data DOM as a series of <value> nodes (as you already know).

    Using a data node’s loadXML method, it’s possible to load arbitrary XML into a data node, replacing its current contents. Given this, you could write script in your list’s Exit event which parses the list’s rawValue property, builds an XML string of the properly-namespaced <doc:value> nodes and loads them into the listbox’s data node in the Data DOM:

    // JavaScript (thanks John!):
    
    // build XML string with wrapping <nodeValue> node:
    var vList = ListBox1.rawValue.split("\n");
    var sXML = "";
    for (var i = 0; i < vList.length; i++)
    {
        sXML += "<doc:value xmlns:doc='doc-namespace'>" +
            vList[i] + "</doc:value>";
    }
    sXML += "</nodeValue>";
    
    // load content of <nodeValue> node into ListBox1's data node,
    //  discarding root <nodeValue> node itself:
    ListBox1.dataNode.loadXML(sXML, true, true);

    The result would look like this, in the output data, assuming you had selected two items in ListBox1:

    <?xml version="1.0" encoding="UTF-8"?>
    <xfa:data xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
       <doc:Application xmlns:doc="doc-namespace">
          <doc:AssociatedBusinessName>
             <doc:value>name1</doc:value>
             <doc:value>name2</doc:value>
          </doc:AssociatedBusinessName>
       </doc:Application>
    </xfa:data>
  12. Duane on September 28th, 2009

    Thank you very much Stephan (and John).

    However, what did the schema you use look like for this element, and how did you bind it?

    In my implementation, I’ve found that this works if the listbox is single-select, but if I change it to multi-select, then the dataNode is null.

    Since it works properly in your sample – it must be because the element definition in the schemas are different (that’s the only thing I can think of).

    Thanks
    Duane

  13. Duane on September 28th, 2009

    Whoops .. Sorry Stefan – spelled your named wrong above ^^^^

  14. Duane on September 29th, 2009

    Hi again Stefan
    I’ve been working through this all day. It must be something different between our schemas. With the workaround that you and John developed – were you able to successfully validate the XML produced against your schema? I can get the data, and can manipulate the dataNode, but it still doesn’t validate.

    Also a side point – I noticed that if I attempted to change the dataNode from
    < value >
    to
    < doc:value > (as doc is my namespace prefix)
    instead of < value xmlns=’myNamespace’ >
    as you have in your sample, I got a General Error being thrown when it attempted to load the XML. Maybe it doesn’t like the colon?

    – Duane

  15. Duane on September 29th, 2009

    Hello Stefan,
    Sorry for bogarting your blog on this issue …

    I was finally able to bind correctly to the schema – I was making a silly error in XMLSpy. The proper schema element for the listbox is as reported above (repeated here for clarity)

    <xsd:element name=”AssociatedBusinessName” minOccurs=”0″ >
    <xsd:complexType>
    <xsd:sequence>
    <xsd:element name=”value” type=”doc:TextType” minOccurs=”0″ maxOccurs=”unbounded’/>
    </xsd:sequence>
    </xsd:complexType>
    </xsd:element>

    The binding on the field would be set to $.AssociatedBusinessName

    Thanks for your help.
    – Duane

  16. Stefan Cameron on September 29th, 2009

    Duane,

    I’m glad you figured it out! In case you’re still curious, this is the schema I used for my test (the namespace is different but as long as namespaces match, that shouldn’t matter). The listbox was bound to “$.BusinessName” which had to be specified manually in the “Object palette > Binding tab > Default Binding property”.

    I will be blogging about multi-selection lists, namespaces and schemas shortly. I will provide a working sample along with a couple of caveats I have come across.

  17. Duane on September 30th, 2009

    Thanks again for your help Stefan. I had not flushed the cache properly in XMLSpy and had been unwittingly validating against the wrong schema for a while.
    The sample works great, and I’ve been able to get the workaround into our forms.
    Please pass my thanks on to John as well.

    I found it a little strange that attempting use the script to rename the <value> element as <NamespacePrefix:value> caused an error with LoadXML. However as you’ve demonstrated, <value xmlns=”myNamespace”> works just as well, so I’m not worrying about it.

    Cheers
    – Duane