apache-poiapache-poi-4

Trying to clear the entire contents of a content control including inner content control


I have a content control that currently looks like this. Using Apache POI 5.2.2 version.

xml-fragment    
....xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape">
  <w:sdtPr>
    <w:rPr>
      <w:sz w:val="24"/>
      <w:szCs w:val="24"/>
    </w:rPr>
    <w:alias w:val="condition:Include Clause B-equals-SOMETHINGELSE"/>
    <w:tag w:val="condition:Include Clause B-equals-SOMETHINGELSE"/>
    <w:id w:val="-352886319"/>
    <w:placeholder>
      <w:docPart w:val="40B8349151E69B4080AC951B34BB7066"/>
    </w:placeholder>
    <w15:color w:val="0000FF"/>
    <w15:appearance w15:val="tags"/>
  </w:sdtPr>
  <w:sdtContent>
    <w:sdt>
      <w:sdtPr>
        <w:rPr>
          <w:sz w:val="24"/>
          <w:szCs w:val="24"/>
        </w:rPr>
        <w:alias w:val="clause:Clause B"/>
        <w:tag w:val="clause:Clause B"/>
        <w:id w:val="2110933031"/>
        <w:placeholder>
          <w:docPart w:val="DE22C8B6F70C8945AFCC799440DC836B"/>
        </w:placeholder>
        <w:showingPlcHdr/>
        <w15:color w:val="0000FF"/>
        <w15:appearance w15:val="tags"/>
      </w:sdtPr>
      <w:sdtContent>
        <w:sdt>
          <w:sdtContent>
            <w:r w:rsidRPr="002619CB">
              <w:rPr>
                <w:color w:val="FF0000"/>
              </w:rPr>
              <w:t xml:space="preserve">This is Clause </w:t>
            </w:r>
            <w:r w:rsidRPr="002619CB">
              <w:rPr>
                <w:color w:val="FF0000"/>
              </w:rPr>
              <w:t>B</w:t>
            </w:r>
                .......       
            <w:r>
              <w:t/>
              <w:cr/>
            </w:r>
          </w:sdtContent>
        </w:sdt>
      </w:sdtContent>
    </w:sdt>
  </w:sdtContent>
</xml-fragment>

And I am using the following code to clear out all the "content" inside the outer content control. So that means the inner content control I want to be removed. In this scenario the second condition gets calls and only clears out the <w:sdtPr> and keeps the inner content control. How do I remove all the content within the outer content control including the inner content control. Thanks

void setContentBlank() {
    if (this.object instanceof CTSdtBlock) {
        CTSdtBlock ctSdtBlock = (CTSdtBlock)this.object
        if (ctSdtBlock.isSetSdtContent()) {
            CTSdtContentBlock sdtContentBlock = ctSdtBlock.getSdtContent()
            sdtContentBlock.PList.clear()
        }
    } else if (this.object instanceof CTSdtRun) {
        CTSdtRun ctSdtRun = (CTSdtRun)this.object
        if (ctSdtRun.isSetSdtContent()) {
            CTSdtContentRun sdtContentRun = ctSdtRun.getSdtContent()
            CTR[] ctRArray = []
            sdtContentRun.setRArray(ctRArray)
        }
    } else if (this.object instanceof CTSdtCell) {
        CTSdtCell ctSdtCell = (CTSdtCell)this.object
        if (ctSdtCell.isSetSdtContent()) {
            CTSdtContentCell sdtContentCell = ctSdtCell.getSdtContent()
            for (int c = 0; c < sdtContentCell.getTcList().size(); c++) {
                CTTc ctTc = sdtContentCell.getTcList().get(c)
                ctTc.PList.clear()
            }
        }
    }
}

Solution

  • The sdtContent of your outer control does not have a PList nor a RArray. It contains a sdt only.

    To clear all content in a content control, the simplest way will be unset the sdtContent first and then add a new empty sdtContent.

    Example code converted to Java code:

    void setContentBlank(XmlObject object) {
        if (object instanceof CTSdtBlock) {
            CTSdtBlock ctSdtBlock = (CTSdtBlock)object;
            if (ctSdtBlock.isSetSdtContent()) {
                ctSdtBlock.unsetSdtContent();
                ctSdtBlock.addNewSdtContent();
            }
        } else if (object instanceof CTSdtRun) {
            CTSdtRun ctSdtRun = (CTSdtRun)object;
            if (ctSdtRun.isSetSdtContent()) {
                ctSdtRun.unsetSdtContent();
                ctSdtRun.addNewSdtContent();
            }
        } else if (object instanceof CTSdtCell) {
            CTSdtCell ctSdtCell = (CTSdtCell)object;
            if (ctSdtCell.isSetSdtContent()) {
                ctSdtCell.unsetSdtContent();
                ctSdtCell.addNewSdtContent();
            }
        }
     }