Editing XML templates

Using templates for data import

If you use a template created for data export, InfoMaker expressions, text, comments, and processing instructions are ignored when data is imported. If you are creating a template specifically for import, do not add any of these items. You need only map column names to element and attribute names.

Every item in the Export/Import Template view has a pop-up menu from which you can perform actions appropriate to that item, such as editing or deleting the item, adding or editing attributes, adding child elements or other items, and inserting elements, processing instructions, CDATA sections, and so forth, before the current item.

If an element has no attributes, you can edit its tag in the Export/Import Template view by selecting it and left-clicking the tag or pressing F2. Literal text nodes can be edited in the same way. You can delete items (and their children) by pressing the Delete key.

The examples in this section show the delimiters used in the XML document. When you edit the template in dialog boxes opened from the Export/Import Template view for XML, you do not need to type these delimiters in text boxes.

The rest of this section describes some of the items in the template. For more information, see the XML specification at http://www.w3.org/TR/REC-xml.

XML declaration

The XML declaration specifies the version of XML being used. You may need to change this value for a future version of XML. It can also contain an encoding declaration and a standalone document declaration. From the pop-up menu, you can edit the declaration, and, if the document is well-formed, delete it. If you have deleted the XML declaration, you can insert one from the Insert Before item on the pop-up menu for the next item in the template.

Encoding declaration

The encoding declaration specifies the character-set encoding used in the document, such as UTF-16 or ISO-10646-UCS-4.

If there is no encoding declaration, the value defaults to UTF-16LE encoding in ASCII environments. In DBCS environments, the default is the default system encoding on the computer where the XML document is generated. This ensures that the document displays correctly as a plain text file. However, since the DBCS data is serialized to Unicode, XML documents that use UTF-16LE, UTF-16 Big Endian, or UTF-16 Little Endian can all be parsed or generated correctly on DBCS systems.

Several other encodings are available, including ASCII, UCS4 Big Endian, UCS4 Little Endian, EBCDIC code pages IBM037 and IBM1140, ISO Latin-1, and Latin 1 Windows (code page 1252). You can select these values from a drop-down list box in the XML Declaration dialog box.

Standalone document declaration

The standalone document declaration specifies whether the document contains no external markup that needs to be processed and can therefore stand alone (Yes), or that there are, or might be, external markup declarations in the document (No). The value in the default template is No, and if there is no standalone document declaration, the value is assumed to be No.

Example

This is an XML declaration that specifies XML version 1.0, UTF-16LE encoding, and that the document can stand alone:

<?xml version="1.0" encoding="UTF-16LE" standalone="yes"?>

Document type declaration

The document type declaration contains or points to markup declarations that provide a grammar for a class of documents. This grammar is known as a document type definition, or DTD. The document type declaration defines constraints on the sequence and nesting of tags, attribute values, names and formats of external references, and so forth. You can edit the document type declaration to change its name, but the name must always be the same as the name of the root element. Changing the name in either the document type declaration or the root element automatically changes the name in the other.

Adding DTDs

You can add an identifier pointing to an external DTD subset, and you can add an internal DTD subset. If you supply both external and internal subsets, entity and attribute-list declarations in the internal subset take precedence over those in the external subset.

Public identifiers

An external identifier can include a public identifier that an XML processor can use to generate an alternative URI. If an alternative URI cannot be generated, the URI provided in the system identifier is used. External identifiers without a public identifier are preceded by the keyword SYSTEM. External identifiers with a public identifier are preceded by the keyword PUBLIC.

Exporting metadata

If you specify a system or public identifier and/or an internal subset in the Document Type Declaration dialog box, a DTD cannot be generated when the data is exported to XML. A MetaDataType of XMLDTD! is ignored. For more information about the properties that control the export of metadata, see Exporting metadata.

Examples

These are examples of valid document type declarations.

An external system identifier:

<!DOCTYPE d_dept_listing SYSTEM "d_dept_listing.dtd">

An external system identifier with a public identifier:

<!DOCTYPE d_test PUBLIC "-//MyOrg//DTD Test//EN"
"http://www.mysite.org/mypath/mytest.dtd">

An external system identifier with an internal DTD. The internal DTD is enclosed in square brackets:

<!DOCTYPE d_orders 
   SYSTEM "http://www.acme.com/dtds/basic.dtd"[
   <!ELEMENT Order (Date, CustID, OrderID, Items*)>
   <!ELEMENT Date (#PCDATA)>
   <!ELEMENT CustID (#PCDATA)>
   <!ELEMENT OrderID (#PCDATA)>
   <!ELEMENT Items (ItemID, Quantity)>
   <!ELEMENT ItemID (#PCDATA)>
   <!ELEMENT Quantity (#PCDATA)>
]>

Root element

You can change the name of the root element, add attributes and children, and insert comments, instructions, and, if they do not already exist, XML and/or document type declarations before it.

Changing the name of the root element changes the name of its start and end tags. You can change the name using the Edit menu item, or in the Element Attributes dialog box. Changing the name of the document type declaration, if it exists, also changes the name of the root element, and vice versa. The root element name is always the same as the document type declaration name.

You can add the following kinds of children to the root element:

  • Elements

  • Text

  • Control references

  • InfoMaker expressions (including column references)

  • CDATA sections

  • Comments

  • Processing instructions

Controls

Adding a control reference opens a dialog box containing a list of the columns, computed fields, report controls, and text controls in the document.

Control references can also be added to empty attribute values or element contents using drag-and-drop from the Control List view. Column references can also be added using drag-and-drop from the Column Specifications view.

Drag-and-drop cannot replace

You cannot drag-and-drop an item on top of another item to replace it. For example, if you want to replace one control reference with another control reference, or with an InfoMaker expression, you first need to delete the control reference you want to replace.

InfoMaker expressions

Adding an InfoMaker expression opens the Modify Expression dialog box. This enables you to create references to columns from the data source of the report. One use of this feature is to return a fragment of XML to embed, providing another level of dynamic XML generation.

Using Date and DateTime with strings

If you use a control reference or an InfoMaker expression that does not include a string to represent Date and DateTime columns in a template, the XML output conforms to ISO 8601 date and time formats. For example, consider a date that displays as 12/27/2004 in the report, using the display format mm/dd/yyyy. If the export template does not use an expression that includes a string, the date is exported to XML as 2004-12-27.

However, if the export template uses an expression that combines a column with a Date or DateTime datatype with a string, the entire expression is exported as a string and the regional settings in the Windows registry are used to format the date and time.

Using the previous example, if the short date format in the registry is MM/dd/yy, and the InfoMaker expression is: "Start Date is " + start_date, the XML output is Start Date is 12/27/04.

Attributes

Controls or expressions can also be referenced for element attribute values. Select Edit/Add Attribute from the pop-up menu for elements to edit an existing attribute or add a new one.

For each attribute specified, you can select a control reference from the drop-down list or enter a literal text value. A literal text value takes precedence over a control reference. You can also use the expression button to the right of the Text box to enter an expression.

The expression button and entry operates similarly to report properties in the Properties view. The button shows an equals sign if an expression has been entered, and a not-equals sign if not. A control reference or text value specified in addition to the expression is treated as a default value. In the template, this combination is stored with the control reference or text value, followed by a tab, preceding the expression. For example:

attribute_name=~"text_val~~tdw_expression~"

Composite and nested reports

Report controls can be referenced in the Detail section of export templates as children of an element.

Nested reports supported for XML export only

Import does not support nested reports. If you attempt to import data in any format, including XML, CSV, DBF, and TXT, that contains a nested report, the nested report is not imported and the import may fail with errors.

Composite reports

For composite reports that use the Composite presentation style, the default template has elements that reference each of its nested reports.

If a composite report contains two reports that have columns with identical names, you must use the procedure that follows if you want to generate an XML document with a DTD or schema. If you do not follow the procedure, you will receive a parsing error such as "Element 'identical_column_name' has already been declared".

  1. Create a template in the first report and select this template in the Use Template list on the Data Export property page.

  2. Create a template in the second report.

  3. If any element name is used in the template in the first report, change it to another name in the template in the second report.

  4. Select the template for the second report in the Use Template list.

  5. Generate the XML document.

These steps are necessary because you cannot use a given element name more than once in a valid DTD or schema.

Nested reports

For report controls added to the detail band of a base report that is related to the inserted report with retrieval arguments or criteria, the report control is available to the export template in two ways:

  • Select an element in the template or add a new element, then select Add Child>DataWindow Control Reference. Any report controls inserted in the detail band are available for selection in the dialog box that displays.

  • Drag a report control from the Control List view and drop it on an existing empty element.

When you export XML using a template that has a reference to a report control, the export template assigned to the nested report with the Use Template property is used, if it exists, to expand the XML for the nested report. If no template is specified for the nested report, the default template is used.

The relationship between the nested report and the base report, for example a Master/Detail relationship, is reflected in the exported XML.

CDATA sections

You can export the name of a column in a CDATA section using the syntax <![CDATA[columnname]]>. You can export the value of a column using the syntax <![CDATA[~t columnname]]>. The ~t is used to introduce an expression. You can also use an expression such as ~t columnname*columnname to export a computed value to the XML.

You can import a value into a column using the syntax <![CDATA[ columnname]]>. Note that this syntax in a template has different results for import and export: it imports the column value but exports the column name.

You cannot import an XML file that has a ~t expression in a CDATA section.

Everything else inside a CDATA section is ignored by the parser. If text contains characters such as less than or greater than signs (< or >) or ampersands (&) that are significant to the parser, it should be defined as a CDATA section. A CDATA section starts with <![CDATA[ and ends with ]]>. CDATA sections cannot be nested, and there can be no white space characters inside the ]]> delimiter -- for example, you cannot put a space between the two square brackets.

Example

<![CDATA[
   do not parse me
]]>

This syntax in an export template exports the value of the column emp_salary:

<![CDATA[~t emp_salary]]>

This syntax in an import template imports the value of the column emp_salary:

<![CDATA[emp_salary]]>

Comments

Comments can appear anywhere in a document outside other markup. They can also appear within the document type declaration in specific locations defined by the XML specification.

Comments begin with <!-- and end with -->. You cannot use the string -- (a double hyphen) in a comment, and parameter entity references are not recognized in comments.

Example

<!-- this is a comment -->

Processing instructions

Processing instructions (PIs) enable you to provide information to the application that uses the processed XML. Processing instructions are enclosed in <? and ?> delimiters and must have a name, called the target, followed by optional data that is processed by the application that uses the XML. Each application that uses the XML must process the targets that it recognizes and ignore any other targets.

The XML declaration at the beginning of an XML document is an example of a processing instruction. You cannot use the string xml as the name of any other processing instruction target.

Example

In this example, usething is the name of the target, and thing=this.thing is the data to be processed by the receiving application:

<?usething thing=this.thing?>

Exporting to XML

You can export the data in a report to XML using the Save Rows As menu item in the Report painter when the Preview view is open and is the last view touched. When you export data, InfoMaker uses an export template to specify the content of the generated XML.

Default export format

If you have not created or assigned an export template, InfoMaker uses a default export format. This is the same format used when you create a new default export template. See Creating templates.

OLE reports cannot be exported using a template. You must use the default format.

Setting data export properties

The Data Export page in the Properties view lets you set properties for exporting data to XML.

The Use Template property

The names of all templates that you create and save for the current report display in the Use Template drop-down list.

The template you select from the list is used to conform the XML to the specifications defined in the named template.

When you open a report, the Export/Import Template view displays the template specified in the report's Use Template property. (If the view is not visible in the current layout, select View>Export/Import Template>XML from the menu bar.) If the property has not been set, the first saved template displays or, if there are no saved templates, the default structured template displays as a basis for editing.

Template used when saving

When the report is saved as XML, InfoMaker uses the template specified in the Use Template property. If the property has not been set, InfoMaker uses the default template.

When you are working on a template, you might want to see the result of your changes. The template specified in the Use Template property might not be the template currently displayed in the Export/Import Template view, so you should check the value of the Use Template property to be sure you get the results you expect.

To save to XML using the current template:

  1. Right-click in the Export/Import template view and select Save or Save As from the pop-up menu to save the current template.

  2. On the Data Export page in the properties view, select the current template from the Use Template drop-down list.

  3. Select File>Save Rows As, select XML from the Files of Type drop-down list, enter a file name, and click Save.

Generating group headers

To generate the contents of the header section iteratively for each group in a group report, check the Iterate Header for Groups check box. This property is on by default.

For example, consider a group report that includes the columns sales_order_id and sales_order_order_date. The following screenshot shows the template for this report:

The root element in the Header section of the template, Orders, has a child element, Order. Order has an id attribute whose value is a control reference to the column sales_order_id. Order also has a child element, OrderDate, that contains a column reference to the sales_order_order_date column. These elements make up the header section that will be iterated for each group.

The Detail Start element, Item, has an id attribute whose value is a control reference to the column sales_order_items_line_id. It also has three child elements that contain column references to the line items for product ID, quantity, and ship date.

When the report is exported with the Iterate Header for Groups property on, the order ID and date iterate for each group. The following XML output shows the first three iterations of the group header:

<?xml version="1.0" encoding="UTF-16LE" standalone="no"?>
<Orders>
   <Order id="2001">
      <OrderDate>2002-03-14</OrderDate>
         <Item id="1">
            <Product>300</Product>
            <Quantity>12</Quantity>
            <ShipDate>2005-09-15</ShipDate>
         </Item>
         <Item id="2">
            <Product>301</Product>
            <Quantity>12</Quantity>
            <ShipDate>2005-09-14</ShipDate>
         </Item>
         <Item id="3">
            <Product>302</Product>
            <Quantity>12</Quantity>
            <ShipDate>2005-09-14</ShipDate>
         </Item>
   </Order>
   <Order id="2002">
      <OrderDate>2002-03-18</OrderDate>
         <Item id="2">
            <Product>401</Product>
            <Qty>24</Qty>
            <ShipDate>2002-09-18</ShipDate>
         </Item>
         <Item id="1">
            <Product>400</Product>
            <Qty>24</Qty>
            <ShipDate>2002-09-18</ShipDate>
         </Item>
   </Order>
   <Order id="2003">
      <OrderDate>2002-03-21</OrderDate>
         <Item id="3">
            <Product>400</Product>
            <Qty>12</Qty>
            <ShipDate>2002-09-23</ShipDate>
         </Item>
         ...

For reports with more than one group, when you generate a new default template, each group after the first is identified with a special icon and a check on the pop-up menu next to the Starts Group Header item.

When the Iterate Header for Groups check box is selected, each XML fragment in the header section between a Group Header element and the next Group Header element or Detail Start element is iterated.

In the template shown in the previous illustration, sales are grouped by customer ID, then by order ID. The customer group header has attributes for the customer's ID and first and last names. The order group header has attributes for the order ID and date. The following illustration shows the report in the Design view:

The following XML output shows the first iteration of the customer group header and the first and second iterations of the order group header:

<?xml version="1.0" encoding="UTF-16LE" standalone="no"?>
<d_customer>
   <customer id="101" fname="Michaels" lname="Devlin">
      <order id="2001" date="1996-03-14">
            <order_item>
            <sales_order_items_line_id>1</sales_order_items_line_id>
            <sales_order_items_prod_id>300</sales_order_items_prod_id>
            <sales_order_items_quantity>12</sales_order_items_quantity>
         </order_item>
         <order_item>
            <sales_order_items_line_id>2</sales_order_items_line_id>
            <sales_order_items_prod_id>301</sales_order_items_prod_id>
            <sales_order_items_quantity>12</sales_order_items_quantity>
         </order_item>
         <order_item>
            <sales_order_items_line_id>3</sales_order_items_line_id>
            <sales_order_items_prod_id>302</sales_order_items_prod_id>
            <sales_order_items_quantity>12</sales_order_items_quantity>
         </order_item>
      </order>
      <order id="2005" date="1996-03-24">
         <order_item>
            <sales_order_items_line_id>1</sales_order_items_line_id>
            <sales_order_items_prod_id>700</sales_order_items_prod_id>
            <sales_order_items_quantity>12</sales_order_items_quantity>
         </order_item>
      </order>

Formatting the exported XML

By default, the XML is exported without formatting. If you want to view or verify the exported XML in a text editor, check the Include Whitespace check box. Turning this property on causes the export process to insert tabs, carriage returns, and linefeed characters into the XML so that it is easier to read. Most of the examples in this chapter were exported with this property turned on.

Do not import formatted XML

You should not try to import XML formatted with white space characters, because the white space between data element tags is considered to be part of the element.

Exporting metadata

You can specify that metadata in the form of a DTD or schema should be exported when you save the report. You can choose to save the metadata with the XML or in a separate file.

If you export metadata as a schema, you can associate it with a namespace. See Associating a namespace with an exported schema.

To specify how metadata should be saved, select a value from the Meta Data Type drop-down list. The possible values are:

  • XMLNone! -- No metadata is generated

  • XMLSchema! -- An XML schema is generated

  • XMLDTD! -- A DTD is generated

If the data item for a column is null or an empty string, an empty element is created. If you select XMLSchema!, child elements with null data items are created with the content "xsi:nil='true'".

The metadata is saved into the exported XML itself or into an associated file, depending on the setting in the SaveMeta Data drop-down list. The possible values are:

  • MetaDataInternal! -- The metadata is saved into the generated XML document or string. To save metadata using the .Data.XML expression syntax, you must use this value.

  • MetaDataExternal! -- The metadata is saved as an external file with the same name as the XML document but with the extension .xsd (for a schema) or .dtd (for a DTD). A reference to the name of the metadata file is included in the output XML document.

Example: internal metadata

For example, if you select XMLDTD! and MetaDataInternal!, the header and first row of the exported XML would look like this for a simple grid report for the contact table in the PB Demo DB. The Include Whitespace property has also been selected and the file name is dtdinternal.xml:

<?xml version="1.0" encoding="UTF-16LE" standalone="yes"?>
<!DOCTYPE dtdinternal [<!ELEMENT dtdinternal (dtdinternal_row*)>
<!ELEMENT dtdinternal_row (id, last_name, first_name, title, street, city, state, zip, phone, fax)>
<!ELEMENT id (#PCDATA)>
<!ELEMENT last_name (#PCDATA)>
<!ELEMENT first_name (#PCDATA)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT street (#PCDATA)>
<!ELEMENT city (#PCDATA)>
<!ELEMENT state (#PCDATA)>
<!ELEMENT zip (#PCDATA)>
<!ELEMENT phone (#PCDATA)>
<!ELEMENT fax (#PCDATA)>
]>
<dtdinternal>
   <dtdinternal_row>
      <id>1</id>
      <last_name>Hildebrand</last_name>
      <first_name>Jane</first_name>
      <title>ma</title>
      <street>1280 Washington St.</street>
      <city>Emeryville</city>
      <state>MI</state>
      <zip>94608</zip>
      <phone>5105551309</phone>
      <fax>5105554209</fax>
   </dtdinternal_row>

Example: external metadata

If you select MetaDataExternal! instead, the generated XML in dtdexternal.xml looks like this:

<?xml version="1.0" encoding="UTF-16LE"?>
<!DOCTYPE dtdexternal SYSTEM "dtdexternal.dtd">
<dtdexternal>
   <dtdexternal_row>
      <id>1</id>
      <last_name>Hildebrand</last_name>
      <first_name>Jane</first_name>
      <title>ma</title>
      <street>1280 Washington St.</street>
      <city>Emeryville</city>
      <state>MI</state>
      <zip>94608</zip>
      <phone>5105551309</phone>
      <fax>5105554209</fax>
   </dtdexternal_row>

The DTD is in dtdexternal.dtd:

<?xml version="1.0" encoding="UTF-16LE"?><!ELEMENT dtdexternal (dtdexternal_row*)>
<!ELEMENT dtdexternal_row (id, last_name, first_name, title, street, city, state, zip, phone, fax)>
<!ELEMENT id (#PCDATA)>
<!ELEMENT last_name (#PCDATA)>
<!ELEMENT first_name (#PCDATA)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT street (#PCDATA)>
<!ELEMENT city (#PCDATA)>
<!ELEMENT state (#PCDATA)>
<!ELEMENT zip (#PCDATA)>
<!ELEMENT phone (#PCDATA)>
<!ELEMENT fax (#PCDATA)>

Associating a namespace with an exported schema

If you export metadata in the form of a schema, you can associate a namespace with the schema. To do so, right-click the root element in the Export/Import template view and select Schema Options from the pop-up menu. In the dialog box, specify the namespace prefix and URI.

When the Meta Data Type property is XMLSchema! and the Save Meta Data property is MetaDataInternal!, so that the XML schema is generated inline, you can specify a name for the root element. If the root element name is specified, it appears in the generated XML.

In the following example, the root element name is Contacts, the namespace prefix is po, and the URI is http://www.example.com/PO1.

The example shows the header and the first row of the generated XML:

<?xml version="1.0" encoding="UTF-16LE" standalone="no"?>
<Contacts>
  <xs:schema xmlns:po="http://www.example.com/PO1"
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      targetNamespace="http://www.example.com/PO1"
      elementFormDefault="qualified"
      attributeFormDefault="unqualified">
    <xs:element name="d_contact_list">
      <xs:complexType>
        <xs:sequence>
          <xs:element ref="d_contact_list_row"
              maxOccurs="unbounded" minOccurs="0"/>
        </xs:sequence>
      </xs:complexType>
    </xs:element>
    <xs:element name="d_contact_list_row">
      <xs:complexType>
        <xs:sequence>
          <xs:element ref="id"/>
          <xs:element ref="last_name"/>
          <xs:element ref="first_name"/>
          <xs:element ref="city"/>
          <xs:element ref="state"/>
        </xs:sequence>
      </xs:complexType>
    </xs:element>
    <xs:element name="id" type="xs:int"/>
    <xs:element name="last_name" type="xs:string"/>
    <xs:element name="first_name" type="xs:string"/>
    <xs:element name="city" type="xs:string"/>
    <xs:element name="state" type="xs:string"/>
  </xs:schema>
  <po:d_contact_list xmlns:po=
        "http://www.example.com/PO1" xmlns:xsi=
        "http://www.w3.org/2001/XMLSchema-instance">
    <po:d_contact_list_row>
      <po:id>1</po:id>
      <po:last_name>Hildebrand</po:last_name>
      <po:first_name>Jane</po:first_name>
      <po:city>Emeryville</po:city>
      <po:state>MI</po:state>
    </po:d_contact_list_row>

By default, the generated XML is not associated with a namespace.