Doug
Doug

Reputation: 7057

Docx4j: Insert item X times after current item under parent

I'm attempting to use DOCX4J to parse and insert content into a template. As part of this template I have loops which I need to copy everything inbetween two markers, and repeat all that content X times.

The relavant code is as follows:

public List<Object> getBetweenLoop(String name){
        String startTag = this.tag_start + name + "_LOOP" + this.tag_end;
        String endTag = this.tag_start + name + this.tag_end;
        P begin_loop = this.getTagParagraph(startTag);
        P end_loop = this.getTagParagraph(endTag);

        ContentAccessor parent = (ContentAccessor) this.getCommonParent(begin_loop, end_loop);

        List<Object> loop = new ArrayList<Object>();

        boolean save = false;
        //Cycle through the content for the parent and copy all the objects that
        //are between and including the start and end-tags
        for(Object item : parent.getContent()){
            if(item.equals(begin_loop) || item.equals(end_loop))
                save = (save) ? false : true;
            if(save || item.equals(end_loop)){
                loop.add(XmlUtils.deepCopy(item));
            }
            if(item.equals(end_loop)){
                //Here I want to insert everything copied X times after the current item and then exit the for loop.
                //This is the part I'm not sure how to do since I don't see any methods "Insert Child", etc.
            }
        }
        return loop;
    }

getTagParagraph successfully returns the object representing the paragraph for the tag sent. This works beautifully.

getCommonParent returns the shared parent between the two supplied tags. This works beautifully.

My problem is, as commented, how to insert the newly copied items into the appropriate place.

Upvotes: 0

Views: 1196

Answers (2)

Doug
Doug

Reputation: 7057

@Ben, thank-you!

If you know of any instances where below wouldn't work, please let me know.

I had actually just figured out something very similar, but ended up changing a lot more code. Below is what I put together.

   public void repeatLoop(String startTag, String endTag, Integer iterations){
        P begin_loop = this.getTagParagraph(startTag);
        P end_loop = this.getTagParagraph(endTag);
        ContentAccessor parent = (ContentAccessor) this.getCommonParent(begin_loop, end_loop);
        List<Object> content = parent.getContent();

        Integer begin_pointer = content.indexOf(begin_loop);
        Integer end_pointer = content.indexOf(end_loop);

        List<Object> loop = new ArrayList<Object>();
        for(int x=begin_pointer; x <= end_pointer; x = x + 1){
            loop.add(XmlUtils.deepCopy(content.get(x)));
        }

        Integer insert = end_pointer + 1;
        for(int z = 1; z < iterations; z = z + 1){
            content.addAll(insert, loop);
            insert = insert + loop.size();
        }
    }

Upvotes: 0

Ben
Ben

Reputation: 7597

If you're looking to insert all the objects you have stored in your loop collection, you simply need to do something like this (in the conditional you've commented):

item.getContent().addAll(loop);

item represents the end_loop object (a paragraph or whatever), and inserts all the objects you've collected into the loop collection. (addAll may require an int argument too, I can't recall, but if it does that's just the desired index within the overall MainDocumentPart.getContent() JAXB document representation).

Upvotes: 1

Related Questions