package cn.flightfeather.supervision.docx4j.simpleDemo;
|
|
import org.docx4j.XmlUtils;
|
import org.docx4j.jaxb.XPathBinderAssociationIsPartialException;
|
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
|
import org.docx4j.openpackaging.parts.JaxbXmlPartXPathAware;
|
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
|
|
import javax.xml.bind.JAXBException;
|
import java.io.File;
|
import java.util.List;
|
|
public class XPathOverDir {
|
|
|
/**
|
* Example of how to find an object in document.xml
|
* via XPath.
|
*
|
* As explained in Getting Started, there are limitations
|
* in the JAXB reference implementation which make this
|
* approach buggy:
|
*
|
* 1. the xpath expressions are evaluated against the XML
|
* document as it was when first opened in docx4j. You
|
* can update the associated XML document once only, by
|
* passing true into getJAXBNodesViaXPath. Updating it again
|
* (with current JAXB 2.1.x or 2.2.x) will cause an error.
|
*
|
* 2. For some objects,JAXB can’t get parent (with getParent)
|
*
|
* 3. For some document, JAXB can’t set up the XPath at all!
|
*
|
* If these problems affect you, you could try using
|
* MOXy as your JAXB implementation (which docx4j supports
|
* as from forthcoming docx4j 3.0). See
|
* http://www.docx4java.org/forums/docx-java-f6/moxy-t1242.html
|
*
|
* Alternatively, the tried and tested approach is
|
* to use TraversalUtil;
|
* see the OpenMainDocumentAndTraverse sample.
|
*
|
*/
|
public static void main(String[] args) throws Exception {
|
|
String inputdir = System.getProperty("user.dir") + "/dd/";
|
|
File dir = new File(inputdir);
|
|
if (dir.isDirectory()) {
|
|
String[] files = dir.list();
|
|
for (int i = 0; i<files.length; i++ ) {
|
System.out.println("\n" + files[i] + "\n\n");
|
|
if (files[i].endsWith("docx")) {
|
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new File(inputdir + "/" + files[i]));
|
MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
|
|
xpathQuery(documentPart, "//w:fldChar[count(w:ffData)=1]");
|
}
|
}
|
|
}
|
|
|
}
|
|
private static void xpathQuery(JaxbXmlPartXPathAware part, String xpath) throws XPathBinderAssociationIsPartialException, JAXBException {
|
|
// String xpath = "//w:t[contains(text(),'scaled')]";
|
//String xpath = "//w:r[w:t[contains(text(),'scaled')]]";
|
|
List<Object> list = part.getJAXBNodesViaXPath(xpath, false);
|
|
System.out.println("got " + list.size() + " matching " + xpath );
|
|
for (Object o : list) {
|
|
//System.out.println(o.getClass().getName() );
|
|
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() );
|
|
// Demonstrate the getParent bug
|
//Object parent = txt.getParent();
|
//System.out.println( "parent: " + XmlUtils.unwrap(parent).getClass().getName() );
|
} else {
|
System.out.println( XmlUtils.marshaltoString(o, true, true));
|
}
|
|
|
|
}
|
|
}
|
|
}
|