问题
Im unfortunatly rather new to docx4j and I am trying to figure out how to check a checkbox within a template that I have. I tried working with Xpaths and get the Node that way but Im not sure I got it right, also even if I manage getting the right Node Im not quite sure how to change the value properly, replacing text I managed to figure out but I havent figured out changing a attribute value yet.
checking the document.xml i found the name of the Checkbox and the attributes it has
<w:fldChar w:fldCharType="begin">
<w:ffData><w:name w:val="Kontrollkästchen1"/>
<w:enabled/>
<w:calcOnExit w:val="0"/>
<w:checkBox>
<w:sizeAuto/>
<w:default w:val="0"/>
</w:checkBox>
And I tried diffrent premutations of Xpaths, for example: //ffData[@name='Kontrollkästchen1']/checkBox
Would this find the Node I want? If not, how could I get the node and change the attribute correctly?
Thank you Magnus
回答1:
If you are using XPaths, you need to take the namespace into account.
Using the XPathQuery sample, you could feed it:
String xpath = "//w:fldChar[./w:ffData/w:checkBox]";
(or a variation, depending which of those three nodes you want to select)
The alternative approach is to traverse the document, for which there is TraversalUtils.
Both of these approaches are explained in docx4j's Getting Started document.
As noted there, Sun/Oracle JAXB XPaths can't be relied if you have modified your objects.
For that reason, a manual traverse can often be better.
Here's an example of how to do it that way.
package org.docx4j.samples;
import java.util.ArrayList;
import java.util.List;
import org.docx4j.TraversalUtil;
import org.docx4j.XmlUtils;
import org.docx4j.TraversalUtil.CallbackImpl;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.wml.FldChar;
public class TraverseFind {
/**
* Example of how to find an object in document.xml
* via traversal (as opposed to XPath)
*
*/
public static void main(String[] args) throws Exception {
String inputfilepath = System.getProperty("user.dir") + "/checkbox.docx";
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new java.io.File(inputfilepath));
MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
Finder finder = new Finder(FldChar.class);
new TraversalUtil(documentPart.getContent(), finder);
System.out.println("got " + finder.results.size() + " of type " + finder.typeToFind.getName() );
for (Object o : finder.results) {
Object o2 = XmlUtils.unwrap(o);
// this is ok, provided the results of the Callback
// won't be marshalled
if (o2 instanceof org.docx4j.wml.Text) {
org.docx4j.wml.Text txt = (org.docx4j.wml.Text)o2;
System.out.println( txt.getValue() );
} else {
System.out.println( XmlUtils.marshaltoString(o, true, true));
}
}
}
public static class Finder extends CallbackImpl {
protected Class<?> typeToFind;
protected Finder(Class<?> typeToFind) {
this.typeToFind = typeToFind;
}
public List<Object> results = new ArrayList<Object>();
@Override
public List<Object> apply(Object o) {
// Adapt as required
if (o.getClass().equals(typeToFind)) {
results.add(o);
}
return null;
}
}
}
The way I've done these examples, they both get you the org.docx4j.wml.FldChar object.
From there, you'll find your CTFFCheckBox inside getFfData().getNameOrEnabledOrCalcOnExit()
If all you want is the check box, then you can adapt either example to fetch just that. That would be simpler.
来源:https://stackoverflow.com/questions/15763778/docx4j-checking-checkboxes