Xpath 我正在使用docx4j读取.docx文件,我需要获取文档的段落并替换字符串

Xpath 我正在使用docx4j读取.docx文件,我需要获取文档的段落并替换字符串,xpath,jaxb,ms-word,docx4j,Xpath,Jaxb,Ms Word,Docx4j,我使用docx4j来读取和解析.docx文件,但当我遍历段落时,它是一次读取而不是全部段落。下面是我正在使用的代码示例 private void replaceAcrAndDef(String acrName, String acrParensName, String oldDef, String newDef){ String XPATH_TO_SELECT_TEXT_NODES = "//w:t"; List<Object> paragraphs = templa

我使用docx4j来读取和解析.docx文件,但当我遍历段落时,它是一次读取而不是全部段落。下面是我正在使用的代码示例

private void replaceAcrAndDef(String acrName, String acrParensName, String oldDef, String newDef){
    String XPATH_TO_SELECT_TEXT_NODES = "//w:t";
    List<Object> paragraphs = template.getMainDocumentPart().getJAXBNodesViaXPath(XPATH_TO_SELECT_TEXT_NODES, true);
    for (Object obj : paragraphs){
        Text text = (Text) ((JAXBElement)obj).getValue();
        String textValue = text.getValue();
        System.out.println(textValue);
 }
private void replaceAcrAndDef(字符串acrName、字符串acrParensName、字符串oldDef、字符串newDef){
字符串XPATH_TO_SELECT_TEXT_NODES=“//w:t”;
列出段落=template.getMainDocumentPart().getJAXBNodesViaXPath(XPATH\u TO\u SELECT\u TEXT\u节点,true);
用于(对象对象对象:段落){
Text Text=(Text)((JAXBElement)obj.getValue();
字符串textValue=text.getValue();
System.out.println(textValue);
}
在上述for循环的一个过程中,这将被理解为第一段-

“团队对任务、测试、行政和一般服务网络和系统具有直接的MDA经验,因此对需求有着深刻的理解。重新组建一个低风险、反应迅速、对任务、流程和优先事项有着既定理解的团队的好处。我们使用了基于

但是它缺少了这一段的最后一部分。这将在连续的过程中出现。我在这里做错了什么

该段的全部内容如下:

团队对任务、测试、管理和一般服务网络和系统具有直接的MDA经验,因此对需求有着深刻的理解。团队的好处是具有对任务、流程和优先级的既定理解的低风险、响应能力强的团队。我们使用基于集成信息技术的角色-基于管理(RBA)的方法与联合承包商、现有流程和补充流程协同工作


我不知道是否有办法获得整个段落,但如果有,那就太好了,因为我需要逐段替换字符串。

Sun/Oracle JAXB中的XPath内容包含许多已知的缺陷,这使得它在实践中不如它的承诺有用

我不使用它,而是使用类似于:

    static class PFinder extends CallbackImpl {

            List<P> paragraphList = new ArrayList<P>();  

            @Override
            public List<Object> apply(Object o) {

                    if (o instanceof P ) {
                          paragraphList .add((P)o);
                    }                      
                    return null;
            }
    }

            PFinder PFinder = new PFinder();
            new TraversalUtil(paragraphs, PFinder);

            for ( P p : pFinder.paragraphList ) { ...
静态类PFinder扩展CallbackImpl{
List

paragraphList=newarraylist

(); @凌驾 公共列表应用(对象o){ if(P的o实例){ 增加((P)o); } 返回null; } } PFinder PFinder=新的PFinder(); 新的TraversalUtil(段落,PFinder); 对于(P:pFinder.paragraphList){。。。

你可以做类似的事情,寻找w:t

或者,如果您真的想继续使用XPath,现在可以试试

更一般地,我建议您考虑使用<强>内容控制DATABIDEND/String >,而不是您的字符串替换方法。在DOXX4J中,内容控件数据绑定提供了一系列的优点,包括:

  • 重复材料(如表中的行)
  • 有条件地包含/排除内容
  • 包含图像(base64编码)
  • XHTML内容的导入

我将我的评论扩展到一个答案:


我猜,段落包含多个文本元素(w:t)。您能提供一个关于此问题的示例文档吗?如何在段落元素上使用TextUtils.extractText提取文本

尝试p.toString()。这里引用了TextUtils,您也可以使用StringWriter来尝试


使用:


我正在使用这些方法执行搜索,并使用docx4j进行替换(灵感来自:

公共静态列表GetAllegementFromObject(对象对象对象,类到搜索){
列表结果=新建ArrayList();
if(obj instanceof JAXBElement)obj=((JAXBElement)obj.getValue();
if(obj.getClass().equals(toSearch))
结果:添加(obj);
else if(ContentAccessor的obj实例){
List children=((ContentAccessor)obj.getContent();
for(对象子对象:子对象){
addAll(getAllegementFromObject(child,toSearch));
}
}
返回结果;
}
公共静态void find和replace(WordprocessingMLPackage doc,String-toFind,String-replacer){
列出段落=GetAllegementFromObject(doc.getMainDocumentPart(),P.class);
对于(对象PAR:段落){
P=(P)PAR;
List Text=getAllegementFromObject(p,Text.class);
用于(对象文本:文本){
Text t=(Text)Text;
if(t.getValue().contains(toFind)){
t、 setValue(t.getValue().replace(toFind,replace));
}
}
}
}

希望这能有所帮助。

我想,该段落包含多个文本元素(w:t)。您可以提供一个关于此问题的示例文档吗?如何使用TextUtils提取文本。在段落元素上使用extractText?如果您可以修改您的问题以包含段落的XML,这将非常有用。上面的段落中有相同的文档。但尚未使用TextUtils。如何获取段落的XML?DocumENT是ZIP文件,因此您可以将文件扩展名更改为“ZIP”并对其进行解压缩。其中包含内容的word/document.xml。项目的工作方式此时我需要进行字符串操作,不幸的是,我无法更改现有的内容。这种方法的问题是,如果要替换,将丢失运行级格式。
// Request paragraphs
final String XPATH_TO_SELECT_TEXT_NODES = "//w:p";
final List<Object> jaxbNodes = wordMLPackage.getMainDocumentPart().getJAXBNodesViaXPath(XPATH_TO_SELECT_TEXT_NODES, true);

for (Object jaxbNode : jaxbNodes){
    final String paragraphString = jaxbNode.toString();
    System.out.println(paragraphString);
}
for (Object jaxbNode : jaxbNodes){
    final StringWriter stringWriter = new StringWriter();
    TextUtils.extractText(jaxbNode, stringWriter);
    final String paragraphString = stringWriter.toString();
    System.out.println(paragraphString);
}
public static List<Object> getAllElementFromObject(Object obj, Class<?> toSearch) {
    List<Object> result = new ArrayList<Object>();
    if (obj instanceof JAXBElement) obj = ((JAXBElement<?>) obj).getValue();

    if (obj.getClass().equals(toSearch))
        result.add(obj);
    else if (obj instanceof ContentAccessor) {
        List<?> children = ((ContentAccessor) obj).getContent();
        for (Object child : children) {
            result.addAll(getAllElementFromObject(child, toSearch));
        }
    }
    return result;
}

public static void findAndReplace(WordprocessingMLPackage doc, String toFind, String replacer){
    List<Object> paragraphs = getAllElementFromObject(doc.getMainDocumentPart(), P.class);
    for(Object par : paragraphs){
        P p = (P) par;
        List<Object> texts = getAllElementFromObject(p, Text.class);
        for(Object text : texts){
            Text t = (Text)text;
            if(t.getValue().contains(toFind)){
                t.setValue(t.getValue().replace(toFind, replacer));
            }
        }
    }
}