Page 1 of 1

Inserting new paragraph in between existing paragraphs.

PostPosted: Sat Feb 09, 2013 4:26 am
by Robb2012
Hello Everyone,
I need assistance in adding a paragraph in the middle of the document.
By using predefined methods like addParagraph or addParagraphOfText defined for the Main document Part, always adds the paragraph at the end of the document.
How do we add a new paragraph in between already existing paragraphs?
Lets say if we know a place holder / a text / word, then how do we replace this text with a new paragraph?

Or is it only possible by directly manipulating the raw xml of the document.xml part?

Your help is really appreciated.
Thanks.
Regards.

Re: Inserting new paragraph in between existing paragraphs.

PostPosted: Sun Feb 10, 2013 7:08 pm
by jason
Please read the Getting Started document.

Re: Inserting new paragraph in between existing paragraphs.

PostPosted: Sat Feb 16, 2013 4:02 am
by Robb2012
Hey Jason,
I went through the Getting Started document, but still haven't figured out how to insert a new paragraph in between existing paragraphs.

I can find the position of a placeholder, but this is at the text run level by using getJAXBNodesViaXPath.
How do I introduce paragraphs at this placeholder's location? (Replace placeholder with new paragraphs)

Your help is highly appreciated.

Thanks.
Regards.

Re: Inserting new paragraph in between existing paragraphs.

PostPosted: Sat Feb 16, 2013 9:09 am
by jason
With MainDocumentPart mdp = wordMLPackage.getMainDocumentPart(),

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
mdp.getJaxbElement().getBody().getContent()
 
Parsed in 0.014 seconds, using GeSHi 1.0.8.4


gives you a List<Object> of the block level objects (ie paragraphs, tables). You can insert at any position in that list in the usual way.

So the trick is to know which position to insert at. There are three approaches:
• manually
• via XPath
• via TraversalUtils

TraversalUtils is the recommended approach. This is mainly because there is a limitation to using XPath in Sun/Oracle JAXB.

Explanations of the three approaches follow. Common to all of them however, is the question of how to identify what you are looking for.
• Paragraphs don't have ID's, so you might search for a particular string.
• Or you might search for the first paragraph following a section break.
• A good approach is to use content controls (which can have ID's), and to search for your content control by ID, title or tag.

Manual approach
The manual approach is to iterate through the block level elements in the document yourself, looking for the paragraph or table or content control which matches your criteria. To do this, you'd use org.docx4j.wml.Body element method:
public List<Object> getEGBlockLevelElts() or getContent()

XPath approach
Underlying this approach is the use of XPath to select JAXB nodes:
MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
String xpath = "//w:p";
List<Object> list = documentPart.getJAXBNodesViaXPath(xpath, false);

You then find the index of the returned node in EGBlockLevelElts.

Beware, there is a limitation to using XPath in JAXB: the xpath expressions are evaluated against the XML document as it was when first opened in docx4j. You can update the associated XML document once only, by passing true into getJAXBNodesViaXPath. Updating it again (with current JAXB 2.1.x or 2.2.x) will cause an error. So you need to be a bit careful!

Robb2012 wrote:I can find the position of a placeholder, but this is at the text run level by using getJAXBNodesViaXPath.


Alter your XPath so that it matches w:p containing the relevant w:t, or try the getParent method (note documented issue with that though)

TraversalUtils approach
TraversalUtil is a general approach for traversing the JAXB object tree in the main document part. TraversalUtil has an interface Callback, which you use to specify how you want to traverse the nodes, and what you want to do to them.
TraversalUtil can be used to find a node; you then get the index of the returned node in EGBlockLevelElts.