http://qs321.pair.com?node_id=249168

set_uk has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to convert Oracle SQL query output to XML. I'm sure someone has tackled this issue previous to me.

I am using the following code to write an XML file:-

$SelectStatement=$SQL->get($StmntTsk{Def},$StmntTsk{Args}) or throw TNBCriticalException("Cannot get SELECT SQL from Phrasebook"); my $XmlOutFile = $fqd_runlogdir.$MSTR::DLM.$StmntTsk{XMLOutput}; my $ya = XML::Handler::YAWriter->new(AsFile => $XmlOutFile); my $generator = XML::Generator::DBI->new( Handler => $ya, dbh => $dbh, ShowColumns => True ); $generator->execute($SelectStatement);

Problem is when I have NULL entries in a database column I get no XML element - when what I want is an empty element. This is because I sometimes want to manipulate the XML into CSV and to have it formatted correctly it needs a comma for each NULL - which I cant do unless I can process a Node in the nodeset via XSL.

Now I know I could change my SQL to wrap these columns with NVL but I thought there might be a way with DBD/Perl to process the NULL's and maintain the elements

Replies are listed 'Best First'.
Re: SQL -> XML Conversion
by mirod (Canon) on Apr 09, 2003 at 08:49 UTC

    It seems to me that you could patch XML::Generator::DBI.

    line 122 is:

    $proxy->send_tag($names->[$i], $row[$i], 3) if defined($row[$i]);

    A quick fix (untested!), that would work just for you would be to replace this by:

    if( defined($row[$i])) { $proxy->send_tag($names->[$i], $row[$i], 3); } else { $proxy->send_tag($names->[$i], '', 3); }

    An even better fix would be to add an option in the new that would control whether SAX events are emitted or not for a NULL column.

    Then send the patch to matts and make his day ;--)

    Update: fixed the code (added brackets around the test). Thanks to gmax who tested it.

Re: SQL -> XML Conversion
by dakkar (Hermit) on Apr 09, 2003 at 15:54 UTC

    There is a very good reason for the current behaviour: NULL gets mapped to no element, empty string gets mapped to empty element.

    If you really need to confuse the two concepts, you can write a SAX filter (put it between the generator and your consumer) which fills in the missing elements.

    On a side note: if you need a CSV, why are you passing through XML?

    -- 
            dakkar - Mobilis in mobile
    

    Most of my code is tested...

    Perl is strongly typed, it just has very few types (Dan)

      I agree it appears confused. My theory was to query the db once - convert to XML then use multiple XSLT passes to build whatever output format I needed be it HTML, CSV or different XML format. It works ok - but the important thing is that I now know a hell of a lot more than when I started

        If you need them to be distributed by a web server, you could give AxKit a try. AxKit comes with the AxKit::XSP::ESQL taglib that you could use to query the database and output XML at your pleasure -which you could them make available as an HTML page or whatever format you like.

        If you are interested in AxKit and the ESQL taglib you could also take a look at this article: Fun with ESQL.

        Ciao!
        --bronto


        The very nature of Perl to be like natural language--inconsistant and full of dwim and special cases--makes it impossible to know it all without simply memorizing the documentation (which is not complete or totally correct anyway).
        --John M. Dlugosz