Page 1 of 1

Best way to remove some elements

PostPosted: Wed Nov 28, 2012 1:04 am
by ricofernandes
Hi! I'm studying the best way to remove elements of some type from a document. In my case, for example, I want to remove all CTPerm and RangePermissionStart from the document. How can I do it? Thanks a lot in advance!

Re: Best way to remove some elements

PostPosted: Wed Nov 28, 2012 9:13 pm
by jason
You need to find the elements first, of course. To do this, you can use TraversalUtils or XPath. I typically use TraversalUtils, since there are some issues with XPath in the JAXB reference implementation (RI). See the example code which finds CTImageData, which you can adapt.

Once you have found an element, you'll want to remove it from the parent list. To get this to work properly, you might need to work around an issue with getParent in the JAXB RI.

There is a workaround in GitHub https://github.com/plutext/docx4j/commi ... 232a552e49 and in the latest nightly release, but for earlier docx4j, you can override walkJAXBElements:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
   private void yourMethod() {

        ShapeFinder bf = new ShapeFinder();
                new TraversalUtil(paragraphs, bf);
       
        for (CTImageData imageReference : bf.shapeRefs)
        {
          // delete it - this code not tested
          Object parent = imageReference.getParent();
          if (parent instanceof ContentAccessor) {
               ((ContentAccessor)parent).getContent().remove(imageReference);
          } else {
            // out of luck .. handle this special case
          }
        }
   }

    static class ShapeFinder extends CallbackImpl {
               
        List<CTImageData> shapeRefs = new ArrayList<CTImageData>();  
               
        @Override
                public List<Object> apply(Object o) {
                       
                        if (o instanceof org.docx4j.vml.CTImageData) {
                                CTImageData imageData = (org.docx4j.vml.CTImageData)o;
                                shapeRefs.add(imageData);
                        }                      
                        return null;
                }
       
        @Override
                public void walkJAXBElements(Object parent) {

                       
                        List children = getChildren(parent);
                        if (children != null) {

                                for (Object o : children) {
                                        o = XmlUtils.unwrap(o);
                                       
                                        // workaround for unreliable getParent
                                        // This workaround is part of docx4j since 3.0.0,
                                        // but duplicated here for earlier users
                                        if (o instanceof Child) {
                                                ((Child)o).setParent(parent);
                                        }
                                       
                                        this.apply(o);
                                        if (this.shouldTraverse(o)) {
                                                walkJAXBElements(o);
                                        }

                                }
                        }
                }
        }
 
Parsed in 0.016 seconds, using GeSHi 1.0.8.4


hope this helps .. Jason