Hi,

> Am 12.10.2015 um 00:46 schrieb Tolen Miller <[email protected]>:
> 
> I'm using version 1.8.10 and had some great help in a previous thread
> (subject: Cannot load pre existing PDF to access fields). I have been able
> to successfully load a pre existing fill-able PDF (created in LiveCycle);
> get a map of text fields from the getFieldNameList() method; then use a
> comparison of the field name on the pdf and name of the database field to
> map values onto the pdf.
> 
> In the end of that thread, I mentioned my own trouble with also filling the
> XFA portion of the form. In the end, I opted to rip out the XFA (acroForm.
> setXFA(null);) in order to get the filled static PDF to display in Adobe's
> products. I have been working on another project in the past few weeks, but
> am again looking at filling the XFA. After looking at the PDXFA, I am
> having trouble getting a similar map or list of text field names from the
> XFA. This was my first attempt, but I'm not getting what I was expecting:


would it be possible to upload a sample form to a public location to take a 
closer look?

> 
> System.out.println("Setting up XFA");
> PDXFA xfa = acroForm.getXFA();
> Document xmlDoc = xfa.getDocument();
> NodeList dataElements = xmlDoc.getElementsByTagName("xfa:data");
> HashMap<String, Integer> xmlFields = new HashMap<String, Integer>();
> if (dataElements != null) {
> for (int i = 0; i < dataElements.getLength(); i++) {
> xmlFields.put(dataElements.item(0).getNodeName(), i);
> }
> }
> 

your need to recurse down into the nodes below xfa:data. Something like



    public static void main(String[] args) throws IOException, 
ParserConfigurationException, SAXException
    {
        PDDocument document = PDDocument.loadNonSeq(...);
        PDXFA xfa = document.getDocumentCatalog().getAcroForm().getXFA();
        Document xmlDoc = xfa.getDocument();
        Node xfaData = xmlDoc.getElementsByTagName("xfa:data").item(0);
        HashMap<String, String> xmlFields = new HashMap<String, String>();

        getDataElements(xfaData, xmlFields);
        
        System.out.println(xmlFields);
        
    }
    
    public static void getDataElements(Node node, HashMap<String, String> 
xmlFields) {
        NodeList nodeList = node.getChildNodes();
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node currentNode = nodeList.item(i);
            if (currentNode.getNodeType() == Node.ELEMENT_NODE && 
currentNode.hasChildNodes()) {
                //calls this method for all the children which is Element
                getDataElements(currentNode, xmlFields);
            } else {
                xmlFields.put(currentNode.getNodeName(), 
currentNode.getNodeValue());
            }
        }
    }


It could also be that xfa:data is empty or doesn't have all fields e.g. for 
dynamic forms. To get the fields as designed you need to look into the template 
node and look for subform and field nodes. Things can get a little more 
complicated as there is a <traversal> and there might be a <bind> elements 
which tell you a little more about the structure of the form and the data 
binding of an element. <bind> is there if the data binding for the field is not 
done by matching the field name. A small snippet below


            <field h="6.35mm" name="txtOrderedByCompanyName" w="82.55mm" 
y="52.07mm">
               <ui>
                  <textEdit>
                     <border>
                        <edge presence="hidden"/>
                        <edge presence="hidden"/>
                        <edge/>
                        <edge presence="hidden"/>
                     </border>
                     <margin/>
                  </textEdit>
               </ui>
               <font size="9pt" typeface="Myriad Pro"/>
               <margin bottomInset="0mm" leftInset="0mm" rightInset="0mm" 
topInset="0mm"/>
               <para marginLeft="0pt" vAlign="middle"/>
               <caption reserve="15.24mm">
                  <para vAlign="middle"/>
                  <value>
                     <text>Company</text>
                  </value>
               </caption>
               <traversal>
                  <traverse ref="header[0].txtOrderedByAddress[0]"/>
               </traversal>
               <bind match="dataRef" ref="$.CompanyName"/>
            </field>


BR
Maruan




> My hope, after that code snippet, was to match on the String of the
> xmlFields map with a field name from my db, then use the int as the
> position of the dataElements list to set the text value (which would show
> as the filled value in the pdf).  Where have I gone wrong?

Reply via email to