Posted on 2008-11-21 14:56:33-08 by dhoworth
finding elements by type
I'm a new user and having trouble finding any way to search by element type (i.e. tag). I'm looking for <office:annotation> elements. I see there is a setAnnotation() method but not apparently a getAnnotation() and I see there is selectElementsByContent() and various other select methods but I can't see anything to search by element type? Or do I need to use the low-level methods? Thanks, Dave
Direct Responses: 9393 | Write a response
Posted on 2008-11-21 15:23:04-08 by jmgdoc in response to 9392
Re: finding elements by type

As soon as you know the tag, you can use an XPath expression, through a low level method such as selectNodesByXPath(). The example below returns the list of the office:annotation elements in the current context (i.e. by default the whole document):
my @annotations = $doc->selectNodesByXPath('//office:annotation');
Direct Responses: 9394 | Write a response
Posted on 2008-11-21 16:19:54-08 by dhoworth in response to 9393
Re: finding elements by type
Thanks for that. I was just concerned by the various exhortations to not use the low-level interface that I might have missed a high-level feature :)

So having got my element, and it's table-cell parent, I have a similar type of question. Is there some method to find the row and column number of the cell (I can't see any), or do I have to iterate through all the cells keeping track of the indices?

Thanks again, Dave
Direct Responses: 9399 | Write a response
Posted on 2008-11-21 20:42:05-08 by jmgdoc in response to 9394
Re: finding elements by type

There is no direct method to find the logical coordinates of a given table cell.

But whatever the element, you can get its parent and its local position, using parent() and pos(). Beware, parent() and pos() are element methods (not document methods), so the local position of a cell is given by
$cell->pos()
and not
$doc->pos($cell)
Both are provided by the underlying XML::Twig module; see the XML::Twig documentation for more details. Alternatively, you could have a look at getLocalPosition(), an undocumented method in the OpenOffice::OODoc::Element package (XPath.pm); this method is a wrapper of pos(). Simply put, you cas get the position of a cell in the row (knowing that the cell's parent is a row), then the position of the row in the table [then the position of the table in its own context, and so on]. Be careful, the return values of pos() follow the XPath convention, not the Perl convention, i.e. they are one-based unlike Perl indices.

Don't forget that this approach works with normalized tables only.
Direct Responses: 9409 | Write a response
Posted on 2008-11-24 14:18:57-08 by dhoworth in response to 9399
Re: finding elements by type
I've nearly got it working now :) Thanks to your help. I can extract the column number:
my $table_cell = $note->parent; my $col = $table_cell->pos - 1;
and that works but when I try to get the row number:
my $table_row = $table_cell->parent; my $row = $table_row->pos - 2;
I get strange numbers. I have normalized the table - thanks for the warning :) I've printed
$table_row->getName
so I know it's definitely a table:table-row but if I print out
$table_row->prev_siblings
I see a whole bunch of table:table-column elements as well as the expected preceding table:table-row elements.

If I look at the content.xml, I see this:
<office:spreadsheet> <table:table table:name="Sheet1" table:print="false" table:style-name="ta1"> <table:table-column table:default-cell-style-name="Default" table:number-columns-repeated=" +28" table:style-name="co1"/> <table:table-row table:style-name="ro1"> <table:table-cell>
So the extra elements are undoubtedly that strange table:table-column element. Is there some way to get the correct row number, short of iterating and counting siblings?

Thanks again, Dave
Direct Responses: Write a response
Perl Weekly newsletter
A free weekly newsletter for people who are busy to read all the blogs. click here to check it out.