Page 1 of 1

setting up content control bindings programmatically

PostPosted: Fri Apr 08, 2011 11:39 pm
by Ganesh
Hi,
I am completely new to docx4j. my project requirement is as follows. We have a docx template which has many place holders to be substitued thro UI application. I created a map to hold all the placeholders as key value pair. I reffered the UnmarshallfromTemplate sample and did the replacing with this sample code. I tried with 2 strings and it got replaced perfectly. My template has 2 or 3 font colors. I tried to replace the entire template with the string values but certain place holders where not getting replaced.. it had value as null instead of the replacing string value. i went through the "Getting started" guide and discovered that font colors, grammer etc will split the keys into different runs. When all the font color was same my replace method works fine.

I wanted to try with the content control xml binding. many people have created the custom xml with the tool kit. but we are not supposed to use the content control tool kit. My question is through the docx4j in java how do i create the custom xml for the existing template without using the toolkit. or how to bind the custom xml with my template to replace the place holders. Iwent through the sample which had medicalChartSample.docx but my customXmlDataStorage for the given itemId is null since i dont have the custom xml when i change the extension of docx to zip. Can you please help me with this issue.

thanks
Ganesh..

Re: Filling out a template with Strings of data

PostPosted: Sat Apr 09, 2011 12:16 am
by Ganesh
Also can you please let me know how to replace the place holders in the docx with the values from the UI(object's attribute) using this customXml. Do we need to supply the values in the customxml or in the code??

thanks
Ganesh

Re: Filling out a template with Strings of data

PostPosted: Sun Apr 10, 2011 3:59 pm
by jason
Ganesh wrote: many people have created the custom xml with the tool kit. but we are not supposed to use the content control tool kit. My question is through the docx4j in java how do i create the custom xml for the existing template without using the toolkit.


May i ask why you aren't supposed to use the content control toolkit?

If you can use the OpenDoPE Word Add-In, that ought to do everything you need.

If you can't use that either, in Java, you'll need to:

- add a CustomXML part containing your XML, and a properties part to that (which allocates/specifies a storeItemId)

- programmatically add w:dataBinding to the w:sdtPr element in the content controls you wish to bind.

Ganesh wrote: or how to bind the custom xml with my template to replace the place holders. Iwent through the sample which had medicalChartSample.docx but my customXmlDataStorage for the given itemId is null since i dont have the custom xml when i change the extension of docx to zip.


See viewtopic.php?f=6&t=381

Re: Filling out a template with Strings of data

PostPosted: Mon Apr 11, 2011 7:42 pm
by Ganesh
Hi,
I am totally sorry for my ignorance in content control data binding since started to work on docx4j few days back. I ran the partList sample file.. I didnt have Part /customXml/item1.xml . All it had was word/document.xml,styles,numbering etc. There was customxml file was in docProps/custom.xml. But it didnt have any item1.xml file.
Still i havent got a clear idea how to add a customxml part and a property part purely in java without using content control toolkit..


kindly help me to understand....

thanks
Ganesh...

Re: Filling out a template with Strings of data

PostPosted: Mon Apr 11, 2011 11:43 pm
by Ganesh
Hi,
After my previous post i ran through all the samples of content control xml binding and have got some idea of how to create a inject xml inside the template. The injection of the customxml folder with item.xml and item1.xml is working fine.. In the createCustomXmlDocument() method i create a xml file with just one element as "company". In my customXMLBinding.docx (input template file) i have just one placeholder "company" for which i need to subsitute the string name"Flynnie". But the generated output file does not have this replaced. I am not sure how setNodeValueAtXPath binds the value from the xml to the generated template file. ((CustomXmlDataStorageImpl) customXmlDataStorage).setNodeValueAtXPath(
"/ns0:company[1]",
name, "xmlns:ns0='http://schemas.medchart'");

works.
Please let me know how to replace the value in the output docx template file.

thanks

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
public class CreateDocxWithCustomXml

{

      public static void main(String[] args)

      throws Exception

      {
            String name = "Flynnie";
            System.out.println("Creating package..");
            String inputfilepath = "C:\\Docx4j_Research\\Letter1.docx";
            WordprocessingMLPackage template=WordprocessingMLPackage.load(new File("C:\\Docx4j_Research\\customXMLBinding.docx"));
           
            CustomXmlDataStoragePart customXmlDataStoragePart =injectCustomXmlDataStoragePart(template.getMainDocumentPart(),
                        template.getParts());
           
            addProperties(customXmlDataStoragePart);
                  CustomXmlDataStorage customXmlDataStorage = customXmlDataStoragePart
                        .getData();

            ((CustomXmlDataStorageImpl) customXmlDataStorage).setNodeValueAtXPath(
                        "/ns0:company[1]",
                        name, "xmlns:ns0='http://schemas.medchart'");

            System.out.println(XmlUtils.w3CDomNodeToString(customXmlDataStorage
                        .getDocument()));

            BindingHandler.applyBindings(template.getMainDocumentPart());

            System.out.println(XmlUtils.marshaltoString(template
                        .getMainDocumentPart().getJaxbElement(), true, true));
           

            template.save(new File("C:\\Docx4j_Research\\customxml2.docx"));

            System.out.println("Done.");

      }

      public static CustomXmlDataStoragePart injectCustomXmlDataStoragePart(Base base, Parts parts)

      {
            CustomXmlDataStoragePart customXmlDataStoragePart =null;
            try

            {

                   customXmlDataStoragePart = new CustomXmlDataStoragePart(
                              parts);

                  CustomXmlDataStorage data = new CustomXmlDataStorageImpl();

                 
                  data.setDocument(createCustomXmlDocument());
                 
                  customXmlDataStoragePart.setData(data);

                  base.addTargetPart(customXmlDataStoragePart);

            }

            catch (Exception e)

            {

                  e.printStackTrace();

            }
            return customXmlDataStoragePart;

      }

      public static Document createCustomXmlDocument()

      {

             DocumentBuilder builder= null;
             Document doc= null;
            try {
                   
                  builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
                  doc = builder.newDocument();
                  org.w3c.dom.Element rootElement = doc.createElement("company");
                  doc.appendChild(rootElement);
                 
                 
                 
            } catch (ParserConfigurationException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
            }
           
             return doc;


      }
     
         public static void addProperties(CustomXmlDataStoragePart customXmlDataStoragePart) throws InvalidFormatException {

           CustomXmlDataStoragePropertiesPart part = new CustomXmlDataStoragePropertiesPart();

           org.docx4j.customXmlProperties.ObjectFactory of = new org.docx4j.customXmlProperties.ObjectFactory();

           DatastoreItem dsi = of.createDatastoreItem();

           String newItemId = "{DD6E220C-54BC-47B3-8AE8-A0A61D4934FF}".toLowerCase();                              

           dsi.setItemID(newItemId);

           part.setJaxbElement(dsi );
      customXmlDataStoragePart.addTargetPart(part);

   }
}

 
Parsed in 0.022 seconds, using GeSHi 1.0.8.4

Re: setting up content control bindings programmatically

PostPosted: Tue Apr 12, 2011 12:06 am
by jason
If you unzip your output docx and look at your customxml part, does it contain the string "Flynnie"?

That's the first thing to check.

If not, does your xml file use the medchart namespace your xpath assumes?

If it does, check the w:databinding in your docx. Does its storeItemId match?

If you want more advice, you'll have to post your customxml part, the item1 props part, and the xml representation of your content control.

ps, this thread belongs in the databinding subforum. i'll move it there in the next day or so.

Re: setting up content control bindings programmatically

PostPosted: Tue Apr 12, 2011 2:19 am
by Ganesh
Hi,
when i unzip my output docx customxml part does not contain the string.the xml file does not use the medchart namespace.There is no w:databinding in the docx.
I have attached the necessary xml file for your reference..

It would be very useful if this issue is resolved for any novice learner regarding customxml binding.

thanks

Re: setting up content control bindings programmatically

PostPosted: Tue Apr 12, 2011 9:20 am
by jason
Ganesh wrote:.the xml file does not use the medchart namespace.


In that case, you shouldn't be using that namespace in the code you quoted:

Code: Select all
((CustomXmlDataStorageImpl) customXmlDataStorage).setNodeValueAtXPath(
"/ns0:company[1]",
name, "xmlns:ns0='http://schemas.medchart'");


Ganesh wrote:There is no w:databinding in the docx.


How can you possibly expect the binding to work then?

You are making things hard for yourself trying to do this programmatically, without first getting a feel for how things work by using the content control toolkit and/or the OpenDoPE Word Add-In!

Re: setting up content control bindings programmatically

PostPosted: Tue Apr 12, 2011 9:58 pm
by Ganesh
Hi,
I didnt have access to see how the control toolkit works for xml binding with the document since i am working on a client network and have issues to download.. Today i got the permission to use the toolkit and actually found out how it automatically binds the data when the .docx output file is opened. Its very simple and easy..
But we need to integrate the .docx with the application hence control toolkit option is the last option.
Can you pls provide pointers whre the exact databinding with the xml happens inside the code. I am aware that CTDataBinding java object has to be used for this.. but can you pls suggest some example..


thanks
Ganesh

Re: setting up content control bindings programmatically

PostPosted: Sat Apr 16, 2011 12:44 pm
by jason