SPUG: Generating XML -- XML::Generator, XML::XPath, nsgmls, etc.
Adam Monsen
meonkeys at hotmail.com
Tue Nov 20 22:46:48 CST 2001
Here's a quick demo of XML::Generator, one I haven't seen mentioned yet.
I've found XML::Writer runs faster, but I like the syntax of XML::Generator.
--BEGIN xml_gen_test.pl----------------------------
#!/usr/bin/perl -w
use XML::Generator;
use strict;
my $xml = XML::Generator->new(escape => 'always',
pretty => 2,
conformance => 'strict');
print $xml->DataTribe(
$xml->SendFunc(
$xml->AcknowledgeAddrs(
$xml->EmailAddress('amonsen at example.com'),
$xml->EmailAddress('meonkeys at hotmail.com'),
),
$xml->ClientName('MarketSuckemdry & Buy, INC.'),
$xml->ImportData(
$xml->Row(
$xml->UserID('0157H7'),
$xml->Column({ Name => 'Car'}, 'Honda'),
$xml->Column({ Name => 'Sex'}, 'Female'),
),
),
),
);
--END xml_gen_test.pl----------------------------
Close all your parens properly and you're guaranteed well-formed XML! This
is basically a compile-time check for well-formedness. It also has easy ways
to handle namespaces, CDATA, comments, <!DOCTYPE... declarations, etc.
Here's the output of the above xml_gen_test.pl:
--START xml output---------------------------------
<DataTribe>
<SendFunc>
<AcknowledgeAddrs>
<EmailAddress>amonsen at example.com</EmailAddress>
<EmailAddress>meonkeys at hotmail.com</EmailAddress>
</AcknowledgeAddrs>
<ClientName>MarketSuckemdry & Buy, INC.</ClientName>
<ImportData>
<Row>
<UserID>0157H7</UserID>
<Column Name="Car">Honda</Column>
<Column Name="Sex">Female</Column>
</Row>
</ImportData>
</SendFunc>
</DataTribe>
--END xml_output---------------------------------
For checking XML validity against a DTD, I use nsgmls. I don't know an easy
way to validate XML with Perl.
For Retrieving data, XML::XPath is a great way to get at a specific piece of
data. I ran this script on xml_output above...
--BEGIN XML-XPath_test.pl--------------------------
#!/usr/bin/perl -w
use XML::XPath;
use XML::XPath::XMLParser;
use strict;
my $xml;
while (<>) { $xml .= $_; }
my $parser = XML::XPath::XMLParser->new(xml => $xml);
my $root_node = $parser->parse;
my $xpath = XML::XPath->new(context => $root_node);
my $clientname = $xpath->find('/DataTribe/SendFunc/ClientName/text()');
print "Client is $clientname for this transaction\n";
--END XML-XPath_test.pl--------------------------
And here is the result.
--BEGIN xpath test output--------------------------
Client is MarketSuckemdry & Buy, INC. for this transaction
--END xpath test output--------------------------
Notice how the amperstand was conveniently un-escaped. Not sure if I made
any dumb mistakes above, but anyway, Good luck! Please let me (and
spug-list) know what you find out.
-Adam
>From: Colin Meyer <cmeyer at helvella.org>
>To: spug-list at pm.org
>Subject: SPUG: Generating XML
>Date: Tue, 20 Nov 2001 11:02:15 -0800
>
>SPUGsters,
>
>Amidst 90% the offtopic messages on this list recently, here's a
>question about dealing with XML from Perl.
>
>I've done a fair bit of work with XML in Perl, but typically it has had
>to do with receiving information formatted in XML, with the task of
>having to decipher the contents and sift the groolly bits of data out.
>My current project adds another task: generating XML to match particular
>DTDs. I'll receive Perl data structures, and need to translate them into
>valid XML.
>
>I've two thoughts on how to do this. In my simple proof-of-concept
>program sketches, they seem to be approximately equal. One is to use a
>template file, and fill in the changing pieces, and the other is to
>create a DOM structure, and then call its $d->toString() method. Does
>anyone on the list have experience with either of these styles of
>generating XML? A third style that I haven't tried would be to create
>a system that would interpret the Perl data structure, and then
>generate SAX events. This also seems easy enough, but I haven't played
>with it yet.
>
>A SAX style pipeline for all processing from input to output won't work
>in this case, as the data from the querying doc is quite different than
>the data of the replying doc.
>
>The tricky bit that I haven't solved is complying to the DTD in such
>a manner that I'll be sure that my generated doc is correct.
>
>Thanks for any advice,
>-C.
>
> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> POST TO: spug-list at pm.org PROBLEMS: owner-spug-list at pm.org
> Subscriptions; Email to majordomo at pm.org: ACTION LIST EMAIL
> Replace ACTION by subscribe or unsubscribe, EMAIL by your Email-address
> For daily traffic, use spug-list for LIST ; for weekly, spug-list-digest
> Seattle Perl Users Group (SPUG) Home Page: http://zipcon.net/spug/
>
>
_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com/intl.asp
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
POST TO: spug-list at pm.org PROBLEMS: owner-spug-list at pm.org
Subscriptions; Email to majordomo at pm.org: ACTION LIST EMAIL
Replace ACTION by subscribe or unsubscribe, EMAIL by your Email-address
For daily traffic, use spug-list for LIST ; for weekly, spug-list-digest
Seattle Perl Users Group (SPUG) Home Page: http://zipcon.net/spug/
More information about the spug-list
mailing list