Page 1 of 1

Need help with simple binding and AbstractMigrator

PostPosted: Thu Apr 13, 2017 7:01 pm
by manish.imaginea
Hi Jason,

Thank you for creating the docx4j library as an open source project to help us all - I really appreciate the hard work that you must have put in over the years.

I am trying to get upto speed on docx4j and I went through the example "FromVariableReplacement.java" at https://github.com/plutext/docx4j/blob/ ... ement.java - I am able to run this example successfully.

Question:

This code takes text of the form ${foo} and then
- converts it into a content control
- injects a question with text 'foo'
- injects an answer with text 'foo'
- injects the correct Xpath to make the binding work.

Problem:
I want to do the same thing in the example, but with a simple bind (ie no questions or conditionals). How do I accomplish this using this example?

I went through the "createParts" method in AbstractMigrator:
Code: Select all
   protected void createParts(WordprocessingMLPackage pkgOut) throws Exception {
   
      // Add OpenDoPE parts to target
      // .. conditions - not that we use this here
      ConditionsPart conditionsPart = new ConditionsPart(new PartName("/customXml/item1.xml")); // name doesn't matter
      pkgOut.getMainDocumentPart().addTargetPart(conditionsPart, AddPartBehaviour.RENAME_IF_NAME_EXISTS); // Word will silently drop the CXPs if they aren't added to the MDP!
      addPropertiesPart(conditionsPart, "http://opendope.org/conditions");
      conditionsPart.setJaxbElement(new Conditions());
      // .. XPaths
      xPathsPart = new XPathsPart(new PartName("/customXml/item1.xml"));
      pkgOut.getMainDocumentPart().addTargetPart(xPathsPart, AddPartBehaviour.RENAME_IF_NAME_EXISTS);
      addPropertiesPart(xPathsPart, "http://opendope.org/xpaths");
      xPathsPart.setJaxbElement(new Xpaths());
      // .. Questions
      questionsPart = new QuestionsPart(new PartName("/customXml/item1.xml"));
      pkgOut.getMainDocumentPart().addTargetPart(questionsPart, AddPartBehaviour.RENAME_IF_NAME_EXISTS);
      addPropertiesPart(questionsPart,"http://opendope.org/questions");
      questionsPart.setJaxbElement(new Questionnaire());
      Questionnaire.Questions questions = new Questionnaire.Questions();
      questionsPart.getJaxbElement().setQuestions(questions);
      
      // .. Standardised Answer format
      standardisedAnswersPart = new StandardisedAnswersPart(new PartName("/customXml/item1.xml"));
      pkgOut.getMainDocumentPart().addTargetPart(standardisedAnswersPart, AddPartBehaviour.RENAME_IF_NAME_EXISTS);
      storeItemID = addPropertiesPart(standardisedAnswersPart, "http://opendope.org/answers");   
      standardisedAnswersPart.setJaxbElement(new Answers());
      
   }



Unfortunately I am facing a roadblock here. I've created an instance of ComponentsPart to hold the custom XML and modified the code as shown below:

Code: Select all
        protected ComponentsPart componentsPart;
        // snipped for brevity
        componentsPart = new ComponentsPart(new PartName(("/customXml/item1.xml")));
        pkgOut.getMainDocumentPart().addTargetPart(componentsPart,RelationshipsPart.AddPartBehaviour.RENAME_IF_NAME_EXISTS);
        addPropertiesPart(componentsPart,"http://opendope.org/answers"); // TODO what namespace should I use here?


What is the namespace that I should use for the Components Part? ( Link: https://github.com/plutext/docx4j/blob/ ... sPart.java )
The "addPropertiesPart" method requires a namespace for this? if so what is the namespace parameter that I should supply for simple XML binding.

There is already a list of XML namespaces for the other components.

What is the namespace that I should use for simple XML inserts? I want to insert something like:
Code: Select all
<?xml version="1.0" encoding="utf-8" ?>
<employees>
  <employee>
    <name>Karina Leal</name>
    <hireDate>1999-04-01</hireDate>
    <title>Manager</title>
  </employee>
</employees>


and then have it bound via Xpath.

Re: Need help with simple binding and AbstractMigrator

PostPosted: Thu Apr 13, 2017 8:30 pm
by jason
You don't need the components part, that's for inserting reusable components.

You can modify the example to omit the questions part.

At that point binding should still work, albeit to standardised "answers" XML.

You can then try modifying things to map to your employees xml.

Re: Need help with simple binding and AbstractMigrator

PostPosted: Thu Apr 13, 2017 10:21 pm
by manish.imaginea
Thank you for the reply, Jason.
Also, thanks for the clarification on the components part.

I understand I can remove the questions and use the existing XPath in the example to bind to the answers format .(<oda:answer>).
To be more specific my question is related to the injection of this employees.xml as a Part (https://github.com/plutext/docx4j/blob/ ... tPart.java) . The "addPropertiesPart" method in AbstractMigrator takes a storage part and a namespace as an argument. In the example the Namespace for Questions, Answers and XPaths have been demonstrated - but I am confused as to what namespace I should for my custom XML.

The "addPropertiesPart" method that I'm talking about is here:
https://github.com/plutext/docx4j/blob/ ... r.java#L81

Re: Need help with simple binding and AbstractMigrator

PostPosted: Fri Apr 14, 2017 9:29 pm
by jason
Since your sample employees XML has no namespace, you should use null. For the null case, https://github.com/plutext/docx4j/commi ... fc2e061d5b is an improvement.

If you amended your sample employees XML to put it in some namespace, you'd use that.

Per http://webapp.docx4java.org/OnlineDemo/ ... aRefs.html

This element specifies the set of XML schemas that are associated with the parent custom XML part. Any number of XML schemas may be referenced, and this collection of schemas shall then be used to validate the contents of the corresponding custom XML part. If this element is present, then the set of XML schemas provided within should be used to validate the contents of the corresponding custom XML part (including the explicit presence of no child elements to specify that no custom XML schemas should be used even if one is present).