Page 1 of 1

Extend to Standard sdt RemovalHandler

PostPosted: Fri Sep 18, 2015 11:48 pm
by DaniloP
Hi Jason,
I've followed your tips about extending the RemovalHandler.xslt;
I ended up with this, which is more similar to pseudo code... ;(
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
  xmlns:aml="http://schemas.microsoft.com/aml/2001/core"
  xmlns:java="http://xml.apache.org/xalan/java"
  xmlns:o="urn:schemas-microsoft-com:office:office"
  xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"
  xmlns:pkg="http://schemas.microsoft.com/office/2006/xmlPackage"
  xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
  xmlns:v="urn:schemas-microsoft-com:vml"
  xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
  xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
  xmlns:WX="http://schemas.microsoft.com/office/word/2003/auxHint"
  xmlns:w10="urn:schemas-microsoft-com:office:word"
  xmlns:xalan="http://xml.apache.org/xalan" 
  exclude-result-prefixes="a aml java o pic pkg r v w wp WX w10">

<xsl:template match="w:sdt">
  <!--  Strips Standard content controls only. -->
    <xsl:choose>
      <xsl:when
        test="count(w:sdtPr/w:dataBinding)=1">
        <xsl:apply-templates select="w:sdtContent/node()" />
       </xsl:when>
      <xsl:otherwise>
        <xsl:copy>
          <xsl:apply-templates select="@* | node()" />
        </xsl:copy>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>


My questions are:
-Starting from the fact that I want to remove <databinding> and related tags, I applied the w:sdtContent/node()" template (which I don't know actually how is built, because I couldn't be able to find it, but I guess, it replaces the all <w:sdt>, with just <w:sdtContent> and his childs). The same holds for the <otherwise> module applied (which, I guess, just leaves everything as it finds it). Am I wrong? Am I missing anything?
-Once I'll have the .xslt done, how do I refer to this in my code ?
I know I'm asking you to be guided step by step, but I'm really in troubles.
Thank you :D

Re: Extend to Standard sdt RemovalHandler

PostPosted: Mon Sep 21, 2015 6:23 pm
by DaniloP
Any help?

Re: Extend to Standard sdt RemovalHandler

PostPosted: Tue Sep 22, 2015 2:43 am
by DaniloP
Hi Jason,
I'm still hoping to get your help.
As you suggested I tried to extend the functionality of the RemovalHandler;
The plan has been:
-Create a CustomXmlDatastoragePart and Rels;
-Add via code the xpath;
-Remove sdt's trying to leave the content;
Code: Select all

CustomXmlDataStoragePart customXmlDataStoragePart = null;
      
        try {
         customXmlDataStoragePart = new CustomXmlDataStoragePart();
      } catch (InvalidFormatException e) {
         logger.error(e);
      }
        Part parent = wordMLPackage.getMainDocumentPart() ;
       
        CustomXmlDataStorage data = null;
      try {
         data = new CustomXmlDataStorageImpl();
      } catch (InvalidFormatException e) {
         logger.error(e);
      }
       
      
      //String str = FileUtils.readFileToString(new File(xmlFilePath));
        org.w3c.dom.Document domDoc = (Document) XmlUtils.neww3cDomDocument();
      domDoc.appendChild(domDoc.createElement("FAKE_DATA_JUST_TO_CREATE_THE_PART"));
      
       
   try {
      data.setDocument(domDoc);
   } catch (Docx4JException e) {
         e.printStackTrace();
      }
      
      customXmlDataStoragePart.setData(data);
      try {
         parent.addTargetPart(customXmlDataStoragePart, AddPartBehaviour.RENAME_IF_NAME_EXISTS);
      } catch (InvalidFormatException e) {
         e.printStackTrace();
      }
      
      CustomXmlDataStoragePropertiesPart part = null;
      try {
         part = new CustomXmlDataStoragePropertiesPart();
      } catch (InvalidFormatException e) {
         e.printStackTrace();
      }
      
      org.docx4j.customXmlProperties.ObjectFactory of = new org.docx4j.customXmlProperties.ObjectFactory();
      
      DatastoreItem dsi = of.createDatastoreItem();
      String newItemId = "{" + UUID.randomUUID().toString() + "}";               
      dsi.setItemID(newItemId);
      
      part.setJaxbElement(dsi);
      
      try {
         customXmlDataStoragePart.addTargetPart(part);
      } catch (InvalidFormatException e) {
         e.printStackTrace();
      }
      
      FileInputStream xmlStream = new FileInputStream(new File(xmlFilePath));
      try {
         customXmlDataStoragePart.getData().setDocument(xmlStream); //TRUE_DATA
      } catch (Docx4JException e2) {
            logger.error(e2);
      }
      
      ClassFinder finderSdtRun = new ClassFinder(SdtRun.class); // <----- change this to suit
      new TraversalUtil(wordMLPackage.getMainDocumentPart().getContent(), finderSdtRun);
      
      System.out.println("got " + finderSdtRun.results.size()  );
      
      for (Object o : finderSdtRun.results) {
                  
         if (o instanceof SdtRun){
            
            SdtPr sdtPr=((SdtRun) o).getSdtPr();
            Tag t = sdtPr.getTag(); // cerca il tag da db e fatti restituire xpath
            
            CTDataBinding ctDataBinding = Context.getWmlObjectFactory().createCTDataBinding();
              //JAXBElement<CTDataBinding> jaxbDB = Context.getWmlObjectFactory().createSdtPrDataBinding(ctDataBinding);
              sdtPr.setDataBinding(ctDataBinding);
              ctDataBinding.setXpath("/stampaPolizzaXML[1]/contraente[1]/codiceFiscale[1]");
              ctDataBinding.setStoreItemID(dsi.getItemID());
               
            }
         Object o2 = XmlUtils.unwrap(o);
         // this is ok, provided the results of the Callback
         // won't be marshalled         
         
         
            System.out.println( XmlUtils.marshaltoString(o, true, true));
         }
      





String path = "C:/Users/danilo petrone/Desktop/Nuova Cartella/stdRemoval.xslt";
         
         
         InputStream templateStream = new FileInputStream(new File(path));
               
               //getClass().getClassLoader()
                    //.getResourceAsStream(path);
         final Source templateSource = new StreamSource(templateStream);
         
         
         Templates sdtTemplate = null;
         try {
            sdtTemplate = org.docx4j.XmlUtils.getTransformerTemplate(templateSource);
         } catch (TransformerConfigurationException e) {
            e.printStackTrace();
         }
         final JAXBResult result = prepareJAXBResult(Context.jc);
         Document mainDOM = marshaltoW3CDomDocument(((JaxbXmlPart<org.docx4j.wml.Document>) parent).getJaxbElement());
         
         org.docx4j.XmlUtils.transform(mainDOM, sdtTemplate, null, result);
         
         
         try {
            ((JaxbXmlPart<org.docx4j.wml.Document>) parent).setJaxbElement(result);
         } catch (JAXBException e) {
         }
         
      } catch (Docx4JException e2) {
         logger.error(e2);
      }
      
      

      File docx;
      try {
         docx = File.createTempFile("tmpDocx", ".docx", new File(homePath));
         Docx4J.save(wordMLPackage,docx, Docx4J.FLAG_NONE);


The .xslt is:
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
  xmlns:aml="http://schemas.microsoft.com/aml/2001/core"
  xmlns:java="http://xml.apache.org/xalan/java"
  xmlns:o="urn:schemas-microsoft-com:office:office"
  xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"
  xmlns:pkg="http://schemas.microsoft.com/office/2006/xmlPackage"
  xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
  xmlns:v="urn:schemas-microsoft-com:vml"
  xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
  xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
  xmlns:WX="http://schemas.microsoft.com/office/word/2003/auxHint"
  xmlns:w10="urn:schemas-microsoft-com:office:word"
  exclude-result-prefixes="a aml java o pic pkg r v w wp WX w10">
 
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="yes"/>



<xsl:template match="w:sdt">
<xsl:apply-templates select="node()|@*"/>
</xsl:template>

<xsl:template match="w:sdt/w:sdtContent">
<xsl:apply-templates select="node()|@*"/>
</xsl:template>         


<xsl:template match="w:sdt/w:sdtPr"/>
<xsl:template match="w:sdt/w:sdtEndPr"/>


 
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>


The result is that I have content controls removed, but my data are removed too.
I know I'm insisting but, I really need this to work

Re: Extend to Standard sdt RemovalHandler

PostPosted: Tue Sep 22, 2015 10:47 am
by jason
In the v3.3.0 branch, I've changed semantics of Quantifier.ALL; it now really means remove all content controls, whether OpenDoPE or not.

See https://github.com/plutext/docx4j/commi ... 11bbc9471c

You can check that branch out and build/use it; see announces/docx4j-3-3-0-dev-builds-t2262.html

Re: Extend to Standard sdt RemovalHandler

PostPosted: Tue Sep 22, 2015 11:41 pm
by DaniloP
Thank you so much Jason!
Now the procedure is:
-Create a CustomXMLDataStorage and related properties-> populate it with your own data;
-Insert Xpaths via code;
-Save the docx;
-Open it again;
-Create BindingHandler-> Bind the data;
-Create RemovalHandler->Remove sdt's;
-Save the docx once again.
Now you have your data inserted and the content control removed.
Ready to convert it! :D