You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@poi.apache.org by Andreas Seeg <an...@gmail.com> on 2012/08/29 15:07:35 UTC

XWPF - Parsing or creating bullet points/numbered lists with POI 3.8

Hi,

I'm currently trying to find out if a certain paragraph of a .docx
document is a bullet point or part of a numbered list, but can't
figure out a way how to do this with XWPF.

What I found out so far by reading the test cases in the source
package is that there is a getNumbering() method for the XWPFDocument
object itself, which might be what I'm looking for when parsing
numbered lists, but I'm at a loss of how to connect the elements of
that list to the paragraph I am currently trying to parse. I also
looked at the methods for paragraphs and runs, some of which I am
already using for style information, but came up empty.

I'm unsure if this has anything to do with what I'm trying to do, but
I also found that a
org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP object
might somehow be obtainable for paragraphs, and that object might
contain the information on numbering/bullet points, but googling for
javadocs about this object was not successful. Could someone explain
to me if this might be what I'm looking for, and if (or if not), link
me to a short explanation regarding this object type?

As I'm also planning on writing out ordered lists or bullet points
from the intermediate, human readable XML document I'm trying to
create by parsing the .docx, pointers on how to do that with XWPF
would be very much appreciated.

Pointers to documentation (other than the javadocs for POI, the test
cases obtainable via the source package, or the archive of this
mailing list) regarding XWPF are very welcome, too!

Thanks for your time,

Andreas Seeg

PS: I found an earlier post with a similar question before writing
this message, but there was no reply to it in the archive. The number
is 17886 - "Identifying List Items in a document"

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


Re: XWPF - Parsing or creating bullet points/numbered lists with POI 3.8

Posted by Mark Beardsley <ma...@tiscali.co.uk>.
The other trick is to have a simple test document and unzip it down to the
raw xml so that you can see how the whole thing hangs together. That way,
you can look to see the names of the elements in the xml markup and this can
help a great deal if you do need to dig down into the xmlbeans layer.
Furthermore, using an IDE (NetBeans, Eclipse, etc) that opens a list of
member names when you place the dot operator after an object reference is a
great help. This allows you to effectively dig around inside the xmlbeans
layer objects for which there is little or no documentation.

After a little more digging, I think that I can safely say it is the client
codes responsibility for incrementing the numbers. In the numbering xml
markup, only the starting values are given for each level and there is no
sign of the actual level number appearing in the document.xml markup. The
basic approach I was adopting was to grab the numID and see if it had
changed since the previous paragraph. If it had then this was a new list, if
it had not then I needed to increment the numbering value for that list
entry. Of course, this is sidestepping the question of how do you know which
level you are dealing with in a multi-level list and it may well be that you
need to step down into the xmlbeans layer to handle this as I could not see
any indication of the numbering level at the XWPFParagraph. Maybe, this is
in the CTP object or maybe it is necessary to dig deeper into the individual
character runs to get at the numbering level. Will continue to play around
when I can and let you know. Bullets should be easier to deal with I think
as all we need to do is grab the character, no incrmenting numbers to worry
about here. The character does seem to be encoded within the xml markup for
the numbering scheme but I only had a very quick glance at this yesterday
and need to experiment further.

My feeling is that once parsing is cracked, creation should also be
possible. It ought to be a matter of attaching the numbering to a paragraph,
creating the numbering scheme if it does not already exist in the document.
Anyway, this is a bridge to cross another day I think.

Sorry for the long post.

Yours

Mark B



--
View this message in context: http://apache-poi.1045710.n5.nabble.com/XWPF-Parsing-or-creating-bullet-points-numbered-lists-with-POI-3-8-tp5710800p5710828.html
Sent from the POI - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


Re: XWPF - Parsing or creating bullet points/numbered lists with POI 3.8

Posted by Mark Beardsley <ma...@tiscali.co.uk>.
Been doing a little bit more digging and think that I can draw the folowing
conclusions;

The markup within the numbering.xml describes the various
numbering/nulleting 'formats' that are used within the document.
Each numbering format can be divided into one or more levels and so far, I
have not found a simple, single level pattern which does not, of course,
mean that they do not exist.
I think that the contents of numbering.xml are parsed by the xmlbeans layer
into an instance of the CTNumbering class and this instance is encapsulated,
in turn, within the XWPFNumbering class instance that it is possible to get
from the document.
I think that each numbering/bulleting format is represented by an instance
of the CTNum class and that an instance of this is encapsulated within the
XWPFNum class.
Neither XWPFNumbering nor XWPFNum currently expose all of the information
you require and it is going to be necessary, as a result, to modify the api.
Furthermore, I think it may be necessary to create a few new classes and
also modify the XWPFParagraph class. As an example, I have found out how to
get at the level information from the paragraph;

numberingLevel =
para.getCTP().getPPr().getNumPr().getIlvl().getVal().intValue();

This allows you to get at the level within the numbering format used to
define the number for a specific paragraph in a list.

I need to fire up the decompiler and take a good dig around within the
xmlbeans layer to see if the CTNumbering and CTNum classes do expose all the
information needed. If they do, it should be possible to add the required
support to the XWPFNumbering and XWPFNum classes and make it possible to
parse numbered/bulleted lists. The final worrying wrinkle to all of this is
how to derive the next number in a list. All the information in
numbering.xml offers is a prescription so to speak and we need to work out
how to decipher that.

Yours

Mark B



--
View this message in context: http://apache-poi.1045710.n5.nabble.com/XWPF-Parsing-or-creating-bullet-points-numbered-lists-with-POI-3-8-tp5710800p5710830.html
Sent from the POI - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


Re: XWPF - Parsing or creating bullet points/numbered lists with POI 3.8

Posted by Mark Beardsley <ma...@tiscali.co.uk>.
Just thought it might be worth posting the code I have started to play around
with. Nothing special but I think it might be modifiable to work, and it
could serve as a reasonable starting point. The basic approach is as
described in my first post, open a document, get the numbering system
object, get the paragraphs and iterate through them. For each para, try to
get the numID. If that returns null then the paragraph is not in a list, if
a BigInteger object is returned then the para is in a list. If the para is
in a list, check to see that we are not already processing that list - if we
are then this is where concerns around levels and incrementing numbers can
be handled. Also, if the para is in a list and it is a 'new' list, get the
numbering system information. Lots of details to work out but it gets us
onto the first rung of the ladder I think.

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package poistuff;

import java.io.*;
import java.math.BigInteger;
import java.util.*;
import org.apache.poi.xwpf.usermodel.*;

/**
 *
 * @author Mark Beardsley
 */
public class NumberingTest {
    
    private final String filename = "C:/temp/Test.docx";
    
    NumberingTest() throws IOException {
        File file = null;
        FileInputStream fis = null;
        XWPFDocument document = null;
        XWPFNumbering numbering = null;
        XWPFParagraph para = null;
        XWPFNum num = null;
        List<XWPFParagraph> paraList = null;
        Iterator<XWPFParagraph> paraIter = null;
        BigInteger numID = null;
        int numberingID = -1;
        try {
            file = new File(filename);
            fis = new FileInputStream(file);
            document = new XWPFDocument(fis);
            
            fis.close();
            fis = null;
            
            numbering = document.getNumbering();
            
            paraList = document.getParagraphs();
            paraIter = paraList.iterator();
            while(paraIter.hasNext()) {
                para = paraIter.next();
                numID = para.getNumID();
                if(numID != null) {
                    if(numID.intValue() != numberingID) {
                        num = numbering.getNum(numID);
                        numberingID = numID.intValue();
                        System.out.println("Getting details of the new
numbering system " + numberingID);
                        System.out.println("It's abstract numID is " +
num.getCTNum().getAbstractNumId().getVal().intValue());
                    }
                    else {
                        System.out.println("Iterating through the
numbers.");
                    }
                }
                else {
                    System.out.print("Null numID ");
                }
                System.out.println("Text " + para.getParagraphText());
            }
        }
        finally {
            if(fis != null) {
                fis.close();
                fis = null;
            }
        }
    }
    
}




--
View this message in context: http://apache-poi.1045710.n5.nabble.com/XWPF-Parsing-or-creating-bullet-points-numbered-lists-with-POI-3-8-tp5710800p5710829.html
Sent from the POI - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


Re: XWPF - Parsing or creating bullet points/numbered lists with POI 3.8

Posted by Andreas Seeg <an...@gmail.com>.
Thank you very much Mark, this is exactly what I was looking for!

If I can implement my parser without further help, I will follow up my
own post with some code samples in a week or so (Do send me a mail if
you want to in the case I don't keep that promise ;-) ).

As I'll probably need to parse multi-level numberings, too, I'll dig
into the documentation right away.

Greetings,

Andreas

2012/8/31 Mark Beardsley <ma...@tiscali.co.uk>:
> Are you still struggling with this Andreas? The reason I asked is that I was
> playing around a little this morning and found how to get at the numbering
> information when parsing the document. The process goes something like this;
>
> Open the document
> Get the XWPFNumbering object from the document.
> Get the list of XWPFParagraphs from the document.
> Ste through the list of paragraphs and as you get each one try to get the
> number ID from it. If this returns null then the paragraph is not in a list.
> If it does not return null, you can use the BigInteger to retrieve, from the
> XWPFNumbering object, details of the numbering/bulleting scheme applied to
> the paragraph.
>
> There are still plenty of details to work out, not the least of which
> concerns levels within multi-level numbering systems but I do think that I
> might have found a way into reading lists.
>
> Let me know if you want to pursue this further.
>
> Yours
>
> Mark B
>
>
>
> --
> View this message in context: http://apache-poi.1045710.n5.nabble.com/XWPF-Parsing-or-creating-bullet-points-numbered-lists-with-POI-3-8-tp5710800p5710822.html
> Sent from the POI - User mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
> For additional commands, e-mail: user-help@poi.apache.org
>

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


Re: XWPF - Parsing or creating bullet points/numbered lists with POI 3.8

Posted by Mark Beardsley <ma...@tiscali.co.uk>.
Are you still struggling with this Andreas? The reason I asked is that I was
playing around a little this morning and found how to get at the numbering
information when parsing the document. The process goes something like this;

Open the document
Get the XWPFNumbering object from the document.
Get the list of XWPFParagraphs from the document.
Ste through the list of paragraphs and as you get each one try to get the
number ID from it. If this returns null then the paragraph is not in a list.
If it does not return null, you can use the BigInteger to retrieve, from the
XWPFNumbering object, details of the numbering/bulleting scheme applied to
the paragraph.

There are still plenty of details to work out, not the least of which
concerns levels within multi-level numbering systems but I do think that I
might have found a way into reading lists.

Let me know if you want to pursue this further.

Yours

Mark B



--
View this message in context: http://apache-poi.1045710.n5.nabble.com/XWPF-Parsing-or-creating-bullet-points-numbered-lists-with-POI-3-8-tp5710800p5710822.html
Sent from the POI - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


Re: XWPF - Parsing or creating bullet points/numbered lists with POI 3.8

Posted by samik <sa...@yahoo.com>.
Hi,

I am looking for a way to *create *a bulleted/numbered list in a XWPF
document. Do you think it is possible in the current version 3.10?

Thanks,
Samik



--
View this message in context: http://apache-poi.1045710.n5.nabble.com/XWPF-Parsing-or-creating-bullet-points-numbered-lists-with-POI-3-8-tp5710800p5715574.html
Sent from the POI - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


Re: XWPF - Parsing or creating bullet points/numbered lists with POI 3.8

Posted by tuncatunc <at...@gmail.com>.
Hi, 
I believe you have a similar problem like mine.
Getting Number from numbered list.
Is there a simple way to do that using groovy/java?

        doc.getParagraphs().each{XWPFParagraph para->
            def numId = para.getNumID()
            if (numId != null){
                def num = numbering.getNum(numId);
                println num.toString() +  para.getText() //+
para.getNumFmt()
            }
        }




--
View this message in context: http://apache-poi.1045710.n5.nabble.com/XWPF-Parsing-or-creating-bullet-points-numbered-lists-with-POI-3-8-tp5710800p5713794.html
Sent from the POI - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


Re: XWPF - Parsing or creating bullet points/numbered lists with POI 3.8

Posted by Andreas Seeg <an...@gmail.com>.
This is not a question, but I felt the need to type a few lines for
other people who might want to work with bullet points or numberings
in .docx files using the capabilities of Apache POI 3.8.

My original task can be described as extracting certain information
from a specifically formatted word file, and outputting that
information in a simple xml document format. Bullet points and
numberings aren't only specially formatted text, but also implicitly
hold the information about their 'level' compared to other bullet
points or numberings, and I was interested in extracting this
information and to discerning both from each other.

With the great pointers and solutions provided by Mark Beardsley
(again a big thanks for that!) I was able to find out if a paragraph
is part of a numbering/bullet point by checking if
currentParagraph.getDocument().getNumbering().getNum(currentParagraph.getNumID())
returns something different than null. Now, as bullet points are a
special kind of numbering (or the other way around), I still had to
find a way to discern them from each other. Sadly, Apache POI didn't
seem to provide something for that yet, so I extracted this
information manually from the right fragment of the original docx-xml.
Please note that I'm pretty new to java, Apache POI, etc, so this is
probably very ugly for better programmers ;-) :

//First we need the ID of the numbering
BigInteger currentParagraphNumberingID=
currentParagraph.getCTP().getPPr().getNumPr().getNumId().getVal();
//, then use it to find the abstract ID
BigInteger currentParagraphAbstractNumID =
currentParagraph.getDocument().getNumbering().getAbstractNumID(currentParagraphNumberingID);
// and use that one to find the right xml fragment object and turn it
into a string
XWPFAbstractNum currentParagraphAbstractNum =
currentParagraphNumbering.getAbstractNum(currentParagraphAbstractNumID);
CTAbstractNum currentParagraphAbstractNumFormatting =
currentParagraphAbstractNum.getCTAbstractNum();
String numberingFormatXmlAsString =
currentParagraphAbstractNumFormatting.toString();

>From that I built an xml document with the namespace
"http://schemas.openxmlformats.org/wordprocessingml/2006/main", get
its first lvl-element, then the first numFmt-element of the
lvl-element, and from that we extract the value of the "val"
attribute. If that value is "decimal", "lowerLetter", etc, we are
dealing with a numbering, and if not, it is probably a bullet point.
Obviously this method will falsely report a bullet point if we forget
to check for certain values that might indicate a numbering (or
something different than a bullet point), but in my case this sufficed
because we only allow standard numberings in our specially formatted
word file.

In hope that this might help somebody

Andreas Seeg

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org