如何转储 XWPFDocument 的 XML 主体?

How can I dump XML body of XWPFDocument?

这看起来应该很容易,但我找不到答案。

使用 Java 8、Apache POI 和 Apache POI-OOXML 4.1.2,我们正在将文档从基于 XML 的 EPUB3 衍生物转换为 DOCX 格式.我是这个项目的新手,正在尝试调试一些东西。作为调试工具包的一部分,我想将 .docx 文件中相当于 document.xml 文件的 XML 转储为可以打印或保存的字符串。

我试过 XWPFWordExtractor,但似乎打印出文本而不是 XML。 我还尝试了 .toString(),它似乎打印出对象的地址,并遍历了 getBodyElementsIterator() 的结果,这也不完全是。

这帮助我打印字节,但不是我想要的 XML:

我只想要类似的东西

public void dumpDocx(final XWPFDocument docx) {
    System.out.println(docx.getBody().toXml().toString());
}

我希望输出为 XML,代表 document.xml 的内容。

一个 *.docx 文件只是一个 ZIP 存档,包含多个 XML 文件和其他文件。因此,在 XWPFDocument.write 之后,结果(文件或字节)可以这样处理,解压缩并查看 /word/document.xml 例如。

但如果想避免写出整个文档,则需要知道 XWPFDocument 内部基于 org.openxmlformats.schemas.wordprocessingml.x2006.main.CT* 个对象,这些对象都扩展 org.apache.xmlbeans.XmlObject。而XmlObject.toString() returns XMLString。对于文档 XMLXWPFDocument.getDocument returns 一个 org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocument1 这是 /word/document.xml.

的表示

所以System.out.println(docx.getDocument().toString());将打印底层CTDocument1的XML。

不幸的是org.apache.xmlbeans.XmlObject只表示元素或属性的内容,而不是元素或属性本身。因此,当您验证或保存 XmlObject 时,您正在验证或保存其内容,而不是其容器。对于 CTDocument1 这意味着,它包含正文元素但不包含文档容器本身。要将文档容器本身作为 XmlObject,需要一个包含 CTDocument1.

org.openxmlformats.schemas.wordprocessingml.x2006.main.DocumentDocument 对象

来自 XWPFDocument 的打印文档 XML 的示例:

import java.io.FileOutputStream;

import org.apache.poi.xwpf.usermodel.*;

public class CreateXWPFDocumentDumpDocumentXML {
    
 static void printDocumentXML(XWPFDocument docx) throws Exception {
     
  String xml;
  
  System.out.println("Contents of org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocument1:");
  org.apache.xmlbeans.XmlObject documentXmlObject = docx.getDocument();
  xml = documentXmlObject.toString();  
  System.out.println(xml);   
  
  System.out.println("Contents of whole DocumentDocument:");
  org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocument1 ctDocument1 = docx.getDocument();
  org.openxmlformats.schemas.wordprocessingml.x2006.main.DocumentDocument documentDocument = org.openxmlformats.schemas.wordprocessingml.x2006.main.DocumentDocument.Factory.newInstance();
  documentDocument.setDocument​(ctDocument1);
  xml = documentDocument.toString();
  System.out.println(xml);
  
 }

 public static void main(String[] args) throws Exception {

  XWPFDocument docx = new XWPFDocument();
  XWPFParagraph paragraph = docx.createParagraph();
  XWPFRun run=paragraph.createRun(); 
  run.setBold(true);
  run.setFontSize(22);
  run.setText("The paragraph content ...");
  paragraph = docx.createParagraph();

  printDocumentXML(docx);

  try (FileOutputStream out = new FileOutputStream("./XWPFDocument.docx")) {
    docx.write(out);
  } 

 }
}