我了解OpenDOPE。当我以编程方式创建用中继标签包裹的段落时,就可以了。当我尝试创建用表包裹的中继器tr时,它会抛出
org.docx4j.openpackaging.exceptions.Docx4JException: Problems applying bindings
at org.docx4j.model.datastorage.BindingTraverserXSLT.traverseToBind(BindingTraverserXSLT.java:237)
at org.docx4j.model.datastorage.BindingHandler.applyBindings(BindingHandler.java:292)
at org.docx4j.model.datastorage.BindingHandler.applyBindings(BindingHandler.java:216)
at org.docx4j.Docx4J.bind(Docx4J.java:554)
但是当我保存文档然后使用Docx4J.load()进行加载然后进行绑定时,效果很好。
编辑 tr的XMLUtils.deepCopy sdtContent中出现问题
/*
* Losing content here?
*
* First, make absolutely sure that what you have is valid.
*
XmlUtils.marshaltoString(tbl);
的结果<w:tbl xmlns:dsp="http://schemas.microsoft.com/office/drawing/2008/diagram" xmlns:cppr="http://schemas.microsoft.com/office/2006/coverPageProps" xmlns:odx="http://opendope.org/xpaths" xmlns:c14="http://schemas.microsoft.com/office/drawing/2007/8/2/chart" xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" xmlns:odgm="http://opendope.org/SmartArt/DataHierarchy" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:dgm="http://schemas.openxmlformats.org/drawingml/2006/diagram" xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture" xmlns:we="http://schemas.microsoft.com/office/webextensions/webextension/2010/11" xmlns:pvml="urn:schemas-microsoft-com:office:powerpoint" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:sl="http://schemas.openxmlformats.org/schemaLibrary/2006/main" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:comp="http://schemas.openxmlformats.org/drawingml/2006/compatibility" xmlns:b="http://schemas.openxmlformats.org/officeDocument/2006/bibliography" xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" xmlns:xvml="urn:schemas-microsoft-com:office:excel" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:oda="http://opendope.org/answers" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:odc="http://opendope.org/conditions" xmlns:cdr="http://schemas.openxmlformats.org/drawingml/2006/chartDrawing" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:odi="http://opendope.org/components" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:lc="http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" xmlns:odq="http://opendope.org/questions" xmlns:wetp="http://schemas.microsoft.com/office/webextensions/taskpanes/2010/11" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid">
<w:tblPr>
<w:tblStyle w:val="TableGrid"/>
<w:tblW w:w="0" w:type="auto"/>
<w:tblLook w:val="04A0"/>
</w:tblPr>
<w:tblGrid>
<w:gridCol w:w="100"/>
</w:tblGrid>
<w:tr>
<w:tc>
<w:tcPr>
<w:tcW w:w="100" w:type="dxa"/>
</w:tcPr>
<w:p/>
</w:tc>
</w:tr>
<w:sdt>
<w:sdtPr>
<w:alias w:val="Repeat"/>
<w:tag w:val="od:repeat=x1"/>
<w:id w:val="2058423626"/>
</w:sdtPr>
<w:sdtContent>
<w:tr>
<w:sdt>
<w:sdtPr>
<w:alias w:val=""/>
<w:tag w:val="od:xpath=x0"/>
<w:id w:val="947420646"/>
<w:dataBinding w:xpath="/invoice[1]/items/item[1]/name" w:storeItemID="{bb8f553d-dc92-4c50-b1cb-06e77bbe149a}"/>
</w:sdtPr>
<w:sdtContent>
<w:tc>
<w:p/>
</w:tc>
</w:sdtContent>
</w:sdt>
</w:tr>
</w:sdtContent>
</w:sdt>
答案 0 :(得分:0)
在JAXB中,内容控件有不同的Java对象,具体取决于它们包装的是块级,行级,单元级还是运行级内容。这些对象都实现接口SdtElement。
类似地,SdtContent也有不同的Java对象,这取决于它们包装的是块级,行级,单元级还是运行级内容。这些对象都扩展了SdtContent。
您必须使用正确的对象,否则您会注意到,deepCopy将无法正常工作。
我已修改您的代码以使用SdtElement和SdtContent
public class ContentControlFactory {
ObjectFactory wmlObjectFactory = getWmlObjectFactory();
public SdtPr createSdtPr(CTDataBinding dataBinding, String tag, String alias) {
SdtPr sdtPr = createSdtPr(tag, alias);
sdtPr.setDataBinding(dataBinding);
return sdtPr;
}
public SdtPr createSdtPr(String tag, String alias) {
Tag t = new Tag();
SdtPr.Alias a = new SdtPr.Alias();
a.setVal(alias);
t.setVal(tag);
SdtPr sdtPr = wmlObjectFactory.createSdtPr();
sdtPr.getRPrOrAliasOrLock().add(a);
sdtPr.setTag(t);
sdtPr.setId();
return sdtPr;
}
public SdtElement createRepeaterControl(Xpaths.Xpath repeaterXpath, Xpaths.Xpath xpath, Object template) {
return createSdt(
createSdtPr("od:repeat=" + repeaterXpath.getId(), "Repeat"),
createSdtContent(createContentControl(xpath, template))
);
}
public SdtElement createRepeaterControl(Xpaths.Xpath repeaterXpath, Object template) {
return createSdt(
createSdtPr("od:repeat=" + repeaterXpath.getId(), "Repeat"),
createSdtContent(template)
);
}
public SdtElement createContentControl(Xpaths.Xpath xpath, Object template) {
return createSdt(
createSdtPr(
createDataBinding(xpath.getDataBinding().getXpath(), xpath.getDataBinding().getStoreItemID()),
"od:xpath=" + xpath.getId(), ""),
createSdtContent(template));
}
public SdtContent createSdtContent(Object template) {
System.out.println(template.getClass().getName() );
SdtContent sdtContent = null;
if (template instanceof Tr) {
sdtContent = wmlObjectFactory.createCTSdtContentRow();
} else {
sdtContent = wmlObjectFactory.createSdtContentBlock();
}
sdtContent.getContent().add(template);
return sdtContent;
}
public SdtElement createConditionControl(Condition condition, Object template) {
return createSdt(
createSdtPr("od:condition=" + condition.getId(), ""),
createSdtContent(template)
);
}
public SdtElement createSdt(SdtPr sdtPr, SdtContent sdtContent) {
SdtElement sdtElement = null;
if (sdtContent instanceof CTSdtContentRow) {
sdtElement = wmlObjectFactory.createCTSdtRow();
} else {
sdtElement = wmlObjectFactory.createSdtBlock();
}
sdtElement.setSdtPr(sdtPr);
sdtElement.setSdtContent(sdtContent);
return sdtElement;
}
public CTDataBinding createDataBinding(String xPath, String storeItemID) {
CTDataBinding dataBinding = wmlObjectFactory.createCTDataBinding();
dataBinding.setXpath(xPath);//xPath - это строка с XPath до XML-элемента, связанного с этим Content Control
dataBinding.setStoreItemID(storeItemID);//storeItemID - это ID корневого XML-элемента, из которого нужно брать данные
return dataBinding;
}
}
并修复了tr的情况。您需要正确处理其他情况。