Page 1 of 1

VariableReplace with XML

PostPosted: Tue Nov 19, 2019 11:54 pm
by nicra
Hi, I'm trying to replace a variable like ${target} in my .docx file with the content of another .docx file.
I tried it, for example, like this:

Code: Select all
// load document that contains the target variable
WordprocessingMLPackage mainPackage = WordprocessingMLPackage.load(new File(mainPath));
MainDocumentPart mainDocPart = mainPackage.getMainDocumentPart();

// load document that contains the content with which the target variable should be replaced
WordprocessingMLPackage insertFromHerePackage = WordprocessingMLPackage.load(new File(insertFromHerePath));

// get the XML of both documents
String xmlMain = XmlUtils.marshaltoString(mainDocPart.getJaxbElement());
String xmlToInsert = XmlUtils.marshaltoString(insertFromHerePackage.getMainDocumentPart().getJaxbElement());

// map "target" variable to XML of second document
HashMap<String, String> variables = new HashMap<>();
variables.put("target", xmlToInsert);

// create the new document from the XML of the first document and the mappings
Document document = (Document) XmlUtils.unmarshallFromTemplate(xmlMain, variables);
mainDocPart.setJaxbElement(document);, new File(outPath));

Mapping a simple String like "Test" to the variable would work, but mapping it to the XML, like I do now, causes the following error messages:
Code: Select all
Caused by: javax.xml.bind.UnmarshalException: unexpected element (URI:"", local:"document").
Expected elements are <{ }text>

Two other errors are the same, but caused by com.sun.istack.internal.SAXParseException2 and the other by javax.xml.transform.TransformerException: com.sun.istack.internal.SAXParseException2.
Another error message says: org.docx4j.openpackaging.exceptions.Docx4JException: Cannot perform the transformation.

Using the method variableReplace causes the same errors and I have seen some old code that leads me to believe it may be possible with unmarshallFromTemplate.

I have also tried the Docx4J web app to generate XML from a Word file and I tried the generated Java code that uses a wml.ObjectFactory and marshaling that element to a string. Both approaches lead to the same errors.

Is it even possible to replace a variable with (Word!) XML content? Is there something I don't know about that may cause the errors? Please let me know if anything is unclear or other information is required.

Thank you for your time and help!

Re: VariableReplace with XML

PostPosted: Wed Nov 20, 2019 3:12 pm
by jason
It isn't intended that you'd replace a variable with XML.

The reason for this is that the variable is typically on the document surface, that is, inside w:r/w:t. That is: <w:r><w:t>${VAR}</w:t></w:r>

So if you replace ${VAR} with XML, you'll end up with XML inside your w:t element, which the file format does not allow.

Could you have a variable at the w:p or w:r level? (which could be swapped for XML) No, since the schema doesn't allow text content (ie the variable) at those levels.

An alternative approach: OpenDope content control databinding does allow escaped Flat OPC XML to be bound.

Or you could do something like: <w:r><w:t>${VAR}</w:t></w:r> but instead of replacing ${VAR}, you replace the grandparent w:r or even w:p.

If you could describe your ultimate goal, there may be other approaches...

Re: VariableReplace with XML

PostPosted: Wed Nov 20, 2019 5:06 pm
by nicra
Thank you!

The ultimate goal would be:

- have one main document
- look for a certain variable
- at this location: repeat a section with elements in a layout (this would be the second document)
- for every repeated section: do its own variableReplace
- I would also like to insert more basic elements (e.g., just bullet points) at a certain location

Flat OPC XML is new to me, I will look into that.
I suppose for the grandparent replacement operation I would need to manually traverse through all the nodes with the TraversalUtil. Is that correct?