【问题标题】:Why use the CTSectPr.Factory.parse method to parse xml labels appear nested by two <w:sectPr> tags为什么使用CTSectPr.Factory.parse方法解析xml标签出现嵌套两个<w:sectPr>标签
【发布时间】:2021-07-21 09:33:48
【问题描述】:

我要在文档中创建 标签到章节。



我有一堆 xml 字符:

        String defaultSectPr =
                "<w:sectPr xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">"
                        +"<w:pgSz w:w=\"11906\" w:h=\"16838\"/>"
                        +"<w:pgMar w:top=\"1701\" w:right=\"1134\" w:bottom=\"1418\" w:left=\"1418\""
                        +" w:header=\"1185\" w:footer=\"913\" w:gutter=\"0\"/>"
                        +"<w:cols w:space=\"425\"/>"
                        +"<w:pgNumType w:start=\"1\"/>"
                        +"<w:docGrid w:type=\"lines\" w:linePitch=\"312\" w:charSpace=\"0\"/>"
                        +"</w:sectPr>";

我想用它来创建标签,所以我使用了以下代码:
        String defaultSectPr =
                "<w:sectPr xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">"
                        +"<w:pgSz w:w=\"11906\" w:h=\"16838\"/>"
                        +"<w:pgMar w:top=\"1701\" w:right=\"1134\" w:bottom=\"1418\" w:left=\"1418\""
                        +" w:header=\"1185\" w:footer=\"913\" w:gutter=\"0\"/>"
                        +"<w:cols w:space=\"425\"/>"
                        +"<w:pgNumType w:start=\"1\"/>"
                        +"<w:docGrid w:type=\"lines\" w:linePitch=\"312\" w:charSpace=\"0\"/>"
                        +"</w:sectPr>";

        CTSectPr ctSectPr = null;
        try {
            ctSectPr = CTSectPr.Factory.parse(defaultSectPr);
            System.out.println(ctSectPr);
        } catch (XmlException e) {
            e.printStackTrace();
        }

        List<CTP> ctps = ctBody.getPList();
        for(CTP ctp : ctps){
            // Get the ctppr label and determine if there is a selectPr label included
            if(ctp.isSetPPr()){
                CTPPr ctpPr = ctp.getPPr();
                if(ctpPr.isSetSectPr()){
                    ctpPr.unsetSectPr();
                    // Create a selectPr label
                    ctpPr.setSectPr(ctSectPr);
            }
        }

但我得到这样的结果:

<w:sectPr>
    <w:sectPr>
        <w:pgSz w:w="11906" w:h="16838"/>
        <w:pgMar w:top="1701" w:right="1134" w:bottom="1418" w:left="1418" w:header="1185" w:footer="913" w:gutter="0"/>
        <w:cols w:space="425"/>
        <w:pgNumType w:start="1"/>
        <w:docGrid w:type="lines" w:linePitch="312" w:charSpace="0"/>
    </w:sectPr>
</w:sectPr>


我不确定问题是否在于对 CtSectPr 对象使用字符串解析,所以我使用方法来构建标签:

                    CTSectPr sectPr = ctpPr.getSectPr();
                    CTPageSz ctPageSz = sectPr.addNewPgSz();
                    ctPageSz.setW(BigInteger.valueOf(11906l));
                    ctPageSz.setH(BigInteger.valueOf(16838l));

                    CTPageMar ctPageMar = sectPr.addNewPgMar();
                    ctPageMar.setTop(BigInteger.valueOf(1701l));
                    ctPageMar.setRight(BigInteger.valueOf(1134l));
                    ctPageMar.setBottom(BigInteger.valueOf(1418l));
                    ctPageMar.setLeft(BigInteger.valueOf(1418l));
                    ctPageMar.setHeader(BigInteger.valueOf(1185l));
                    ctPageMar.setFooter(BigInteger.valueOf(913l));
                    ctPageMar.setGutter(BigInteger.valueOf(0l));


                    sectPr.addNewCols().setSpace(BigInteger.valueOf(452l));
                    sectPr.addNewPgNumType().setStart(BigInteger.valueOf(1l));

                    CTDocGrid ctDocGrid = sectPr.addNewDocGrid();
                    ctDocGrid.setType(STDocGrid.LINES);
                    ctDocGrid.setLinePitch(BigInteger.valueOf(312l));
                    ctDocGrid.setCharSpace(BigInteger.valueOf(0l));


没错:

<w:sectPr>
 <w:pgSz w:w="11906" w:h="16838"/>
 <w:pgMar w:top="1701" w:right="1134" w:bottom="1418" w:left="1418" w:header="1185" w:footer="913" 
 w:gutter="0"/>
 <w:pgNumType w:start="1"/>
 <w:cols w:space="452"/>
 <w:docGrid w:type="lines" w:linePitch="312" w:charSpace="0"/>
</w:sectPr>

所以我猜这里有问题(我不知道是否正确):

 ctSectPr = CTSectPr.Factory.parse(defaultSectPr);


感谢 Axel Richter 的回答,它确实解决了我的问题,并且提供了一个思路,可以将这个方向的 xml 标签解析为 poi。

【问题讨论】:

    标签: java apache-poi word


    【解决方案1】:

    XmlObject.Factory.parse 方法期望从 XML 解析一个对象,它是 XML 元素(内部 XML)的 content。但是您的String defaultSectPr 包含CTSectPr 的外部XML。

    对于一些主根OOXML 元素有特殊的*Document 对象。这些可以从整个文档 XML 中解析出来,然后只提供获取单个根元素的方法。例如CommentsDocument 提供CTComments getComments()。

    当然CTSectPr 没有这样的文档元素。但是可以从CTSectPr 的外部XML 中解析CTSectPr 的父元素之一,然后从父元素的getSectPr() 方法中获取CTSectPr。例如CTPPr 是CTSectPr 的父元素并提供getSectPr()。

    例子:

    ...
    CTSectPr ctSectPr = null;
    try {
        CTPPr ctPPr = CTPPr.Factory.parse(defaultSectPr);
        ctSectPr = ctPPr.getSectPr();
        System.out.println(ctSectPr);
    } catch (Exception e) {
        e.printStackTrace();
    }
    ...
    

    【讨论】:

      猜你喜欢
      • 2011-09-24
      • 1970-01-01
      • 1970-01-01
      • 2011-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-04
      相关资源
      最近更新 更多