Merge XML and JSON
DocxFactory allows you to merge XML and JSON (and any data structure that you can convert to XML and JSON) in a single merge method instead of using multiple setClipboardValue and paste methods.
Merge XML and JSON Exercise
Open merge.docx in the DocxFactory/exercises/templates/ directory.
Open the Bookmark dialog box to view the bookmarks. The template continues the fields exercise (see picture below).
Compile the template.
Create the .DOCX file.
Copy and run the code below.
import com.docxfactory.WordProcessingMerger; public class runme { public static void main(String argv[]) { try { long startTime = System.currentTimeMillis(); WordProcessingMerger.load( "/opt/DocxFactory/exercises/templates/merge.dfw"); WordProcessingMerger.merge( "<Accounts>" + "<Account>" + "<Line>" + "<LineDate>1/1/99</LineDate><LineAmt>0</LineAmt><LineDesc>Desc0</LineDesc>" + "</Line>" + "<Line>" + "<LineDate>1/1/99</LineDate><LineAmt>1</LineAmt><LineDesc>Desc1</LineDesc>" + "</Line>" + "</Account>" + "</Accounts>"); WordProcessingMerger.merge( "{\"Account\": [{" + "\"Line\": [{" + "\"LineDate\": \"1/1/99\", \"LineAmt\": 2, \"LineDesc\": \"Desc2\"" + "}, {" + "\"LineDate\": \"1/1/99\", \"LineAmt\": 3, \"LineDesc\": \"Desc3\"" + "}]" + "}]}"); WordProcessingMerger.save("/tmp/merge.docx"); System.out.println( "Completed (in " + (double) (System.currentTimeMillis() - startTime) / 1000 + " seconds)."); } catch (Throwable e) { System.err.println(e); } } } |
The code introduces the merge method in the WordProcessingMerger class (see details below).
WordProcessingMerger.merge Method
Merges XML or JSON with the template. The merge method recognizes if the string passed to the method is XML or JSON from the beginning of the string.
When merging XML, DocxFactory drills down the entire XML document. When it reaches a node with the same name as an item, it reads all the node children with the same name as the item fields and sets the field clipboard value with the node content, it then pastes the item and continues drilling the rest of the children (that are not field nodes).
When merging JSON, DocxFactory drills down the entire JSON document. When it reaches an object property with the same name as an item or an object in an array property with the same name as an item, it reads all the value properties (string, number, boolean or null values) with the same name as the item fields and sets the field clipboard value with the property value, it then pastes the item and continues drilling the object.
Declaration:
public static void merge(String p_data);
Parameters:
p_data – XML or JSON string.
Merge XML Notes:
To make the merge simple and flexible, DocxFactory finds item nodes only if the node name matches an item name and does not take into consideration the node parents so you can put the node in another container node (for example: <items><item/>…</items>) or not put the node in any other node (except the document root node) and it would not change the result.
When reading an item node, if a child node has the same name of both an item field and another item, DocxFactory will treat the node as a field because there is no way of knowing if the node is meant to be used as a field or an item. To avoid confusion between items and fields, do not name items and fields with the same name.
To set a chart field, in the field node insert a list of point nodes with a series, category and value nodes and their values. For example: <chart><point><series>Amount</series> <category>01/01/1999</category><value>100</value></point>…</chart>. You can also use <x>, <y> and <size> tags instead of <series>, <category> and <value> tags for X, Y and Size charts.
DocxFactory supports CDATA sections for entering data that is not parsed and may contain illegal XML characters (like "<" and "&") without the need to escape these characters. You can use CDATA to set HTML and RTF field values or any field values that may contain illegal XML characters without the need to escape these characters.
When setting a field value from the content of a node, the complete inner node content is used including XML tags not just text which allows you to enter HTML tags for HTML fields. Note that even though HTML in some cases may not be well formed, the node content must be well formed XML otherwise you will have to use a CDATA section.
To enter new lines in field values, use a new line character (ASCII #10) or escape the character using the " " XML entity. "\n" is not a character escape sequence in XML.
The item names are not case sensitive. For example: the tag name “<Account>” and “<account>” refer to the same item.
The field names are not case sensitive. For example: the tag name “<LineDate>” and “<linedate>” refer to the same field.
Merge JSON Notes:
Just like merging XML, DocxFactory finds item objects only if the object property name matches an item name and does not take into consideration the object parents so you can put the object in another container object or even put all the items in object properties in an array of objects in the document root object (for example: {"items": [{"item": {}}, ...]}) and it would not change the result.
To set a chart field, in the field property value enter an array of objects with a series, category and value properties and their values. For example: "chart": [{"series": "Amount", "category": "01/01/1999", "value": 100}, …]. You can also use "x":, "y": and "size": properties instead of "series":, "category": and "value": properties for X, Y and Size charts.
The JSON property names must be enclosed in quotes according to the JSON specification otherwise a JSON parsing error will be returned.
The item names are not case sensitive. For example: the property name "Account": and "account": refer to the same item.
The field names are not case sensitive. For example: the property name "LineDate": and "linedate": refer to the same field.
Open the created .DOCX file (see picture below).