XML::SAX::Writer(3)
okay so bestie, welcome to the XML::SAX::Writer(3) page from the User Contributed Perl Documentation π. This is the SAX2 XML Writer, version 0.57, and we're gonna walk through it together. no cap, it's giving useful. β¨
β¨ NAME β¨
XML::SAX::Writer β SAX2 XML Writer. periodt.
π VERSION π
version 0.57 π
π¦ SYNOPSIS π¦
okay so here's the vibe check:
use XML::SAX::Writer;
use XML::SAX::SomeDriver;
my $w = XML::SAX::Writer->new;
my $d = XML::SAX::SomeDriver->new(Handler => $w);
$d->parse('some options...');
π₯ DESCRIPTION π₯
π Why yet another XML Writer ? π
so a new XML Writer had to happen to match the SAX2 effort, because quite naturally no existing writer understood SAX2. The first intention had been to start patching XML::Handler::YAWriter, since it had previously been the favourite writer in the SAX1 world. π«Ά
but the more it got patched, the more it became obvious that what was supposed to be a simple patch β mostly adding a few event handlers and changing the attribute syntax β was turning into a rewrite because of various ideas collected along the way. Besides, there was no elegant way found to make it work with SAX2 without breaking the SAX1 compatibility that people are probably still using. There are of course ways to do that, but most require user interaction, which is something that was wanted to be avoided. π
so in the end there was a new writer. ngl it's actually better this way, because it helps keep SAX1 and SAX2 separated. π
π METHODS π
new(%hash)β This is the constructor for this object. It takes a number of parameters, all of which are optional.Outputβ This parameter can be one of several things.- If it is a simple scalar, it is interpreted as a filename which will be opened for writing.
- If it is a scalar reference, output will be appended to this scalar.
- If it is an array reference, output will be pushed onto this array as it is generated.
- If it is a filehandle, then output will be sent to this filehandle.
- Finally, it is possible to pass an object for this parameter, in which case it is assumed to be an object that implements the consumer interface described later in the documentation.
- If this parameter is not provided, then output is sent to
STDOUT. - > important, bestie: there is no means to set an encoding layer on filehandles created by this module. If this is necessary, the calling code should first open a filehandle with the appropriate encoding set, and pass that filehandle to this module. π
Escapeβ This should be a hash reference where the keys are character sequences that should be escaped and the values are the escaped form of the sequence. By default, this module will escape the ampersand (&), less than (<), greater than (>), double quote ("), and apostrophe ('). Note that some browsers don't support the'escape used for apostrophes, so you should be careful when outputting XHTML. If you only want to add entries to theEscapehash, you can first copy the contents of%XML::SAX::Writer::DEFAULT_ESCAPE.CommentEscapeβ Comment content often needs to be escaped differently from other content. This option works exactly as the previous one, except that by default it only escapes the double dash (--) and that the contents can be copied from%XML::SAX::Writer::COMMENT_ESCAPE.EncodeFromβ The character set encoding in which incoming data will be provided. This defaults toUTF-8, which works for US-ASCII as well. Set this toundefif you do not wish to decode your data.EncodeToβ The character set encoding in which output should be encoded. Again, this defaults toUTF-8. Set this toundefif you don't want to encode your data.QuoteCharacterβ Set the character used to quote attributes. This defaults to single quotes (') for backwards compatibility.
π THE CONSUMER INTERFACE π
XML::SAX::Writer can receive pluggable consumer objects that will be in charge of writing out what is formatted by this module. Setting a Consumer is done by setting the Output option to the object of your choice instead of to an array, scalar, or file handle as is more commonly done (internally those in fact map to Consumer classes and are simply available as options for your convenience). π¦
If you don't understand this, don't worry. You don't need it most of the time. π
That object can be from any class, but must have two methods in its API. It is also strongly recommended that it inherits from XML::SAX::Writer::ConsumerInterface so that it will not break if that interface evolves over time. There are examples at the end of XML::SAX::Writer's code.
The two methods that it needs to implement are:
output STRINGβ (Required) This is called whenever the Writer wants to output a string formatted in XML. Encoding conversion, character escaping, and formatting have already taken place. It's up to the consumer to do whatever it wants with the string.finalize()β (Optional) This is called once the document has been output in its entirety, during theend_documentevent.end_documentwill in fact return whateverfinalize()returns, and that in turn should be returned byparse()for whatever parser was invoked. It might be useful if you need to provide feedback of some sort.
Here's an example of a custom consumer. Note the extra $ signs in front of $self; the base class is optimized for the overwhelmingly common case where only one data member is required and $self is a reference to that data member.
package MyConsumer;
@ISA = qw( XML::SAX::Writer::ConsumerInterface );
use strict;
sub new {
my $self = shift->SUPER::new( my $output );
$$self = ''; # Note the extra '$'
return $self;
}
sub output {
my $self = shift;
$$self .= uc shift;
}
sub get_output {
my $self = shift;
return $$self;
}
And here is one way to use it:
my $c = MyConsumer->new;
my $w = XML::SAX::Writer->new( Output => $c );
## ... send events to $w ...
print $c->get_output;
If you need to store more than one data member, pass in an array or hash reference:
my $self = shift->SUPER::new( {} );
and access it like:
sub output {
my $self = shift;
$$self->{Output} .= uc shift;
}
π THE ENCODER INTERFACE π
Encoders can be plugged in to allow one to use one's favourite encoder object. Presently there are two encoders: Encode and NullEncoder. They need to implement two methods, and may inherit from XML::SAX::Writer::NullConverter if they wish to.
new FROM_ENCODING, TO_ENCODINGβ Creates a new Encoder. The arguments are the chosen encodings.convert STRINGβ Converts that string and returns it.
Note that the return value of the convert method is not checked. Output may be truncated if a character couldn't be converted correctly. To avoid problems the encoder should take care of encoding errors itself, for example by raising an exception. π
π¦ CUSTOM OUTPUT π¦
This module is generally used to write XML β which it does most of the time β but just like the rest of SAX it can be used as a generic framework to output data, the opposite of a non-XML SAX parser. π¦
Of course there's only so much that one can abstract, so depending on your format this may or may not be useful. If it is, you'll need to know the following API (and probably to have a look inside XML::SAX::Writer::XML, the default Writer).
initβ Called before the writing starts, it's a chance for the subclass to do some initialisation if it needs it.setConverterβ This is used to set the proper converter for character encodings. The default implementation should suffice but you can override it. It must set$self->{Encoder}to an Encoder object. Subclasses should call it.setConsumerβ Same as above, except that it is for the Consumer object, and that it must set$self->{Consumer}.setEscaperRegexβ Will initialise the escaping regex$self->{EscaperRegex}based on what is needed.escape STRINGβ Takes a string and escapes it properly.setCommentEscaperRegexandescapeComment STRINGβ These work exactly the same as the two above, except that they are meant to operate on comment contents, which often have different escaping rules than those that apply to regular content.
π TODO π
- proper UTF-16 handling
- the formatting options need to be developed.
- test, test, test (and then some tests)
- doc, doc, doc (actually this part is in better shape)
- remove the
xml_decland replace it with intelligent logic, as discussed on perl-xml - make a the Consumer selecting code available in the API, to avoid duplicating
- add an Apache output Consumer, triggered by passing
$rasOutput
π CREDITS π
Michael Koehne (XML::Handler::YAWriter) for much inspiration, and Barrie Slaymaker for the Consumer pattern idea, the coderef output option and miscellaneous bugfixes and performance tweaks. Of course the usual suspects (Kip Hampton and Matt Sergeant) helped in the usual ways. π«Ά
β SEE ALSO β
XML::SAX::*
π AUTHORS π
- Robin Berjon
<robin@knowscape.com> - Chris Prather
<chris@prather.org>
πΈ COPYRIGHT AND LICENSE πΈ
This software is copyright (c) 2014 by Robin Berjon.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
okay that's the whole page, bestie π«Ά. This was XML::SAX::Writer(3) from the User Contributed Perl Documentation β perl v5.42.0, dated 2017-07-25. slay and happy parsing! πβ¨
π¦ where this page comes from
- opensuse-leap 16.0: perl-XML-SAX-Writer 0.57-160000.2.2 Β· Artistic-1.0 or GPL-1.0+
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms