3 March 2008
A working knowledge of LiveCycle Designer (including how to bind fields to data) and XML is important. You should also have a basic understanding of the LiveCycle ES workflow environment, including the LiveCycle Workbench ES tool.
With Adobe LiveCycle Designer ES and the other Adobe LiveCycle ES software you can create multi-record output from a single XML file. If your XML file contains multiple records, you can design a single template and create multiple output records for PDFs and printed formats such as PCL, PostScript and ZPL.
This article will show you how to configure the XML file, create a template with data bindings, and call LiveCycle Output ES server to generate the output. I will also discuss a few tricks that will increase the performance of the Output ES server.
To use this technique, all of your data records must be in a single XML file. The XML file may contain other information, but each record should be in its own node. For example; imagine that we are developing a data-driven information sheet for an online media company. The company's product information is stored in a database and can be exported in an XML format. We want a single XML file with a subnode for each product:
<?xml version="1.0" encoding="UTF-8"?> <products> <book> <title>Assault On Reason</title> <author>Gore, Al</author> <publisher>Penguin Press</publisher> <orderInfo> <isbn> <ten>1594201226</ten> <thirteen>978-1594201226</thirteen> </isbn> <weight>590 g</weight> <price>18.85</price> </orderInfo> </book> <game> <title>Halo 3</title> <platform>Xbox 360</platform> <ASIN>B000FRU0NU</ASIN> <price>49.99</price> </game> <book> <title>The Fly-Tying Bible</title> <author>Gathercole, Peter</author> <publisher>Barron's Educational Series</publisher> <orderInfo> <isbn> <ten>0764155504</ten> <thirteen>978-0764155505</thirteen> </isbn> <weight>681 g</weight> <price>22.02</price> </orderInfo> </book> <dvd> <title>The Italian Job</title> <director>F. Gary Gray</director> <ASIN>B0000B1OFL</ASIN> <price>10.17</price> </dvd> <book> <title>The Pragmatic Programmer</title> <author>Hunt, Andrew and Thomas, David</author> <publisher>Addison-Wesley Professional</publisher> <orderInfo> <isbn> <ten>020161622X</ten> <thirteen>978-0201616224</thirteen> </isbn> <weight>540 g</weight> <price>35.90</price> </orderInfo> </book> <dvd> <title>Battlestar Galactica Miniseries</title> <director>Michael Rymer</director> <ASIN>B00064AFBE</ASIN> <price>31.16</price> </dvd> <book> <title>A Paddler's Guide to Ontario</title> <author>Callan, Kevin</author> <publisher>Boston Mills Press</publisher> <orderInfo> <isbn> <ten>1550463853</ten> <thirteen>978-1550463859</thirteen> </isbn> <weight>300 g</weight> <price>14.56</price> </orderInfo> </book> <game> <title>Guitar Hero 3 Legends of Rock</title> <platform>PlayStation2</platform> <ASIN>B000TGB4V4</ASIN> <price>54.99</price> </game> </products>
Notice that there is a root node—products—that contains a single subnode for each product. There are nodes for books, games and DVDs, but each product record has its own node.
For this example I have also created a schema for this XML file. This is not really necessary, but many database systems will generate a schema, and it will enable me to demonstrate some other features in LiveCycle Designer.
Next, I'll show you how to design the form that will become your information sheet. For the sake of this exercise, assume that you need to create a separate template for each media type in the data file; that is, you will have different templates for books, games, and DVDs. I will be using Adobe LiveCycle Designer ES to create the template.
Once you have started LiveCycle Designer, create a new form. Since the ultimate outcome of this article is to have a document with data, you will need to have a way of specifying which data goes into which fields in your form. Given that your data is in an XML format, this leaves you with two main options: either you can make the form's field hierarchy exactly match the XML data's hierarchy, or you can use a Data Connection to bind the XML data to specific fields. I find that using a Data Connection allows me more freedom when designing the form and provides a level of separation between the design and the data. In this article I will demonstrate the Data Connection operation.
You will need to create a Data Connection (in the Data View) so you can bind the form fields to the XML data. I have provided an XML schema for this sample, but you could also bind to a sample XML file. On the Data View tab, right-click and choose New Data Connection (see Figure 1).
Select the XSD and specify the XML Data root node name (see Figure 2; in this case, I will use "products").
Click the Finish button to complete the Data Connection creation. If you look at the Data View (see Figure 3), you will see the schema hierarchy including the book, game, and dvd nodes.
You can create form fields from the Object Library or by dragging nodes from the Data View onto the form. Either way, you will need to bind the forms to the Data Connection so the data will appear in the proper fields (if your form hierarchy precisely matches the data hierarchy, you can use "normal" binding—but that is not the focus of this article).
If you dragged the fields from the Data View, then the binding will be automatically created. If you created fields from the Object Library, you can create the bindings by dragging and dropping the Data View fields to the form or by using the Default Binding field on the Binding tab (Object pallet; see Figure 4).
In my example, I created fields for all of the nodes under the book node. I will not need the game and dvd nodes for this template, so they can be ignored.
If your XML data file only contained one record, this binding would be fine; however the XML file in this example has multiple records. This will require some changes to the bindings.
Note: Depending on the version of LiveCycle Designer you are using and how the form was created, you may see a
$record notation before the root node. You can ignore this notation for the sake of this discussion.
Allow me to digress for a bit. I've seen form templates in which there is one large repeating subform at the page level. When the data is merged with the template, a new form is created for each record. Although the output of this method looks very similar to the output of the method I describe below, the way that LiveCycle handles them is quite different.
I highly recommend avoiding the one massive repeating subform method when you have several records in your XML. The method I describe below is much more memory-efficient and therefore much better performing. It is better to create the form to use one record and allow LiveCycle Output ES to create the additional files.
You want to change the bindings on the fields to bind to one record. Click a field and edit the Default Binding (on the Binding tab in the Object pallet). Remove the
[*] from the root node (if your data has repeating subforms, you can still have the
[*] on sub nodes—just remove it from the root). For example, the original binding for Title looks like:
book[*].title. Modify it to look like:
When you remove the
[*] from the root, you are telling LiveCycle to create only one form for one record. Since the entire form is not a repeating element, if you don't make the change, you will only see one record once you call LiveCycle Output ES.
If you have a document in which fields are organized in subforms, you will need to change the bindings at both the subform and the field level. I recommend starting at the form level and working your way down through the subforms to the field level. This will be easier because certain versions of Designer may try to "fix" the binding of lower-level elements when their parent elements have changed. Essentially, this means that the
rootnode[*] gets added back into lower level bindings.
For performance reasons, it is also advisable to modify all of the bindings in a fields subform stack, rather than just changing the binding of the lowest elements. For example, if you have a data binding that looks like
journals.author[*].cost.field1, it is best to bind each of field1's parent elements rather than just binding field1. Note: in this example, the author field is a repeating data node. This is okay, since author is not the root node.
You should now have a properly bound template; it's time to look at the setup of the LiveCycle Output ES call. The description below is for LiveCycle Workbench ES; however, the same information applies when you call LiveCycle Output ES through the API or web service.
Create a process that reads your XML file and uses the generatePDFOutput operation under the Ouput service (see Figure 5) this will also work for the generatePrintedOutput operation if you are generating PCL, PS or ZPL formats.
Set the Transformation Format to PDF and specify the Form and Content Root fields so the LiveCycle ES software can find your template. Specify the XML data file in the Input Data field and a document variable in the PDF Output field.
Now that the process has access to the template and the XML data, there are two ways to inform the LiveCycle ES software what constitutes a record—the record level and record name.
Setting the Record Level field tells LiveCycle Output ES to examine the XML data and to create a new form for each node at a particular level. To figure out the record level, start counting at the root node of the XML and add one for each level you go down. For example, if you look at the product XML data, product is the root, so it is at level 1. Book, game and dvd nodes are next, so they are level 2. Since I want to bind to the book node, I would choose a level 2.
This works fine if all of the records in the XML data are of the same type; however, in this case if I was to use a Record Level of 2 I would get several blank forms in my result. This is because the product XML data has a mix of various record types. Instead I will want to filter out the XML data so I only get the appropriate records.
You can have LiveCycle Output ES only generate output documents for specific record types. For example, the XML file has records for books, DVDs, and games. You can tell Output to ignore DVDs and games and just generate output for books.
Under the PDF Output Options, set the Record Name to book. This will tell the LiveCycle ES software to examine the XML file book objects as records. It also tells the LiveCycle ES software to ignore records that do not have the XML tag
Note: Record Name and Record Level are mutually exclusive.
In my sample I just write the PDF out to the file system, but you can handle it as you see fit. Once you run your process, you should see a PDF with four pages: each page should be one of the book records from the XML file.
If you have separate templates for each record type, you can have LiveCycle Output ES select the correct template for each record in the XML file. For example, if you have separate XDP files for books, DVDs, and games, you can have LiveCycle Output ES choose the appropriate template for each record. This will result in an output that mixes templates.
I have created separate templates for books (BookForm.xdp), DVDs (DvdForm.xdp), and games (GameForm.xdp). Add a Generate PDF Output operation to your workflow and set the fields as you did in the previous section. This time, however, leave the Record Name field blank. In the Pattern Matching Rules section, click the "+" button to add a rule. In the Pattern field, add the name of the record as it appears in the XML. In the Form section, add the form name and path (see Figure 6).
When you run this process, Output will read the XML file and will change the template for each of the separate record types.
Please see the official Adobe documentation for more information.