You may wish for more flexibility, such as the possibility
to write a VOTable document with a more complicated
structure than a simple VOTABLE/RESOURCE/TABLE one,
or to have more control over the output destination for referenced STREAM data.
In this case you can use the
VOSerializer
class which handles only the output of TABLE elements themselves
(the hard part), leaving you free to embed these in whatever XML
superstructure you wish.
Once you have obtained your VOSerializer
by specifying
the table it will serialize and the data format it will use,
you should invoke its
writeFields
method followed by
either
writeInlineDataElement
or
writeHrefDataElement
.
For inline output, the output should be sent to the same stream
to which the XML itself is written. In the latter case however,
you can decide where the streamed data go, allowing possibilities such
as sending them to a separate file in a location of your choosing,
creating a new MIME attachment to a message, or sending it down
a separate channel to a client. In this case you will need to
ensure that the href associated with it (written into the STREAM element's
href
attribute) will direct a reader to the right place.
Here is an example of how you could write a number of inline tables in TABLEDATA format in the same RESOURCE element:
void writeTables( StarTable[] tables ) throws IOException { BufferedWriter out = new BufferedWriter( new OutputStreamWriter( System.out ) ); out.write( "<VOTABLE version='1.1'>\n" ); out.write( "<RESOURCE>\n" ); out.write( "<DESCRIPTION>Some tables</DESCRIPTION>\n" ); for ( int i = 0; i < tables.length; i++ ) { VOSerializer.makeSerializer( DataFormat.TABLEDATA, tables[ i ] ) .writeInlineTableElement( out ); } out.write( "</RESOURCE>\n" ); out.write( "</VOTABLE>\n" ); out.flush(); }and here is how you could write a table with its data streamed to a binary file with a given name (rather than the automatically chosen one selected by
VOTableWriter
):
void writeTable( StarTable table, File binaryFile ) throws IOException { BufferedWriter out = new BufferedWriter( new OutputStreamWriter( System.out ) ); out.write( "<VOTABLE version='1.1'>\n" ); out.write( "<RESOURCE>\n" ); out.write( "<TABLE>\n" ); DataOutputStream binOut = new DataOutputStream( new FileOutputStream( binaryFile ) ); VOSerializer.makeSerializer( DataFormat.BINARY, table ) .writeHrefTableElement( out, "file:" + binaryFile, binOut ); binOut.close(); out.write( "</TABLE>\n" ); out.write( "<RESOURCE>\n" ); out.write( "<VOTABLE>\n" ); out.flush(); }
VOSerializer contains some more fine-grained methods too which can be used if you want still further control over the output, for instance to insert some GROUP elements after the FIELDs in a table. Here is an example of that:
BufferedWriter out = new BufferedWriter( new OutputStreamWriter( System.out ) ); out.write( "<VOTABLE version='1.1'>\n" ); out.write( "<RESOURCE>\n" ); out.write( "<TABLE>\n" ); VOSerializer ser = VOSerializer .makeSerializer( DataFormat.TABLEDATA, table ); ser.writeFields( out ); out.write( "<GROUP><FIELDref ref='RA'/><FIELDref ref='DEC'/></GROUP>" ); ser.writeInlineTableElement( out ); out.write( "</TABLE>\n" ); out.write( "</RESOURCE>\n" ); out.write( "</VOTABLE>" );
Note that since STIL v4.1, alongside >writeInlineDataElement(BufferedWriter) VOSerializer has another method >writeInlineDataElementUTF8(OutputStream). This does the same thing, but allows some optimisations, so can be used for better performance if you know that the UTF-8 XML encoding is in use.