XML::S...Record(3pm)

πŸ“¦
version 0.46 Β· 2 versions
  • 0.46 Β· debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking (latest)
  • 0.46 Β· ubuntu jammy
, in debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking

NAME πŸ’–

okay bestie, listen UP: XML::SAX::ByRecord is a record oriented processing situation for (data) documents. that's the whole vibe. that's it. periodt. ✨

(also yes this page is XML::S...Record in the header because the terminal is dramatic and truncates things, but the real name is the full one up there πŸ‘†)


VERSION πŸŽ€

version 0.46 β€” that's the one, no cap.


SYNOPSIS πŸ¦‹

use XML::SAX::Machines qw( ByRecord ) ;

my $m = ByRecord(
    "My::RecordFilter1",
    "My::RecordFilter2",
    ...
    {
        Handler => $h, ## optional
    }
);

$m->parse_uri( "foo.xml" );

like. look at it. you pass it filters, you optionally pass it a Handler, you call parse_uri, done. iconic behavior honestly πŸ’…


DESCRIPTION 🌸

so XML::SAX::ByRecord is a SAX machine that treats a document as a series of records. everything before and after the records just gets emitted as-is, no notes, while the records themselves get excerpted into little mini-documents and run <em>one at a time</em> through the filter pipeline that lives inside ByRecord. it's giving ✨assembly line✨.

the output is a document that has the exact same things before, after, and between the records that the input document did β€” but each record has been run through a filter. so if a document has 10 records in it, the per-record filter pipeline will see 10 sets of ( start_document, body of record, end_document ) events. example below, don't worry bestie 🫢

this has several use cases:

  • Big, record oriented documents β€” big documents can be treated a record at a time with various DOM oriented processors like XML::Filter::XSLT.
  • Streaming XML β€” small sections of an XML stream can be run through a document processor without holding up the stream. main character energy, the stream does NOT wait πŸ’…
  • Record oriented style sheets / processors β€” sometimes it's just plain easier to write a style sheet or SAX filter that applies to a single record at a time, rather than having to run through a series of records. lowkey true.

Topology 🧚

here's how the innards look, and yes it's giving circuit diagram:

   +-----------------------------------------------------------+
   |                  An XML:SAX::ByRecord                     |
   |    Intake                                                 |
   |   +----------+    +---------+         +--------+  Exhaust |
 --+-->| Splitter |--->| Stage_1 |-->...-->| Merger |----------+----->
   |   +----------+    +---------+         +--------+          |
   |               \                            ^              |
   |                \                           |              |
   |                 +---------->---------------+              |
   |                   Events not in any records               |
   |                                                           |
   +-----------------------------------------------------------+

the "Splitter" is an XML::Filter::DocSplitter by default, and the "Merger" is an XML::Filter::Merger by default. that line that bypasses the "Stage_1 ..." filter pipeline? that's for all events that do not occur in a record. all events that do occur in a record pass through the filter pipeline. simple as πŸ“

Example πŸ”₯

here's a quick little filter to uppercase text content:

package My::Filter::Uc;

use vars qw( @ISA );
@ISA = qw( XML::SAX::Base );

use XML::SAX::Base;

sub characters {
    my $self = shift;
    my ( $data ) = @_;
    $data->{Data} = uc $data->{Data};
    $self->SUPER::characters( @_ );
}

and here's a little machine that uses it:

$m = Pipeline(
    ByRecord( "My::Filter::Uc" ),
    \$out,
);

when fed a document like:

<root> a
    <rec>b</rec> c
    <rec>d</rec> e
    <rec>f</rec> g
</root>

the output looks like:

<root> a
    <rec>B</rec> c
    <rec>C</rec> e
    <rec>D</rec> g
</root>

(ngl i am not going to explain the letters in that output, that's just what it says, iykyk πŸ’€)

and the My::Filter::Uc got three sets of events like:

start_document
start_element: <rec>
characters:    'b'
end_element:   </rec>
end_document

start_document
start_element: <rec>
characters:    'd'
end_element:   </rec>
end_document

start_document
start_element: <rec>
characters:   'f'
end_element:   </rec>
end_document

three whole mini-documents. three whole start_document / end_document pairs. it ate. πŸ‘‘


NAME (again πŸ’–)

yep, we're doing it twice, the original does it twice, so:

XML::SAX::ByRecord β€” Record oriented processing of (data) documents.


METHODS πŸ’œ

  • new
my $d = XML::SAX::ByRecord->new( @channels, \%options );

longhand for calling the ByRecord function exported by XML::SAX::Machines. that's it. that's the method. ✨


CREDIT ⭐

proposed by Matt Sergeant, with advise by Kip Hampton and Robin Berjon. (yes the original says "advise", we do not correct the elders πŸ’…)

Writing an aggregator. πŸ™ˆ

to be written. pretty much just that "start_manifold_processing" and "end_manifold_processing" need to be provided. see XML::Filter::Merger and it's source code for a starter.

not me telling you the docs are literally just "to be written" β€” bestie they SAID that. it's in the source of truth, we honor it 🫢

AUTHORS 🌈

  • Barry Slaymaker
  • Chris Prather <chris@prather.org>

this software is copyright (c) 2013 by Barry Slaymaker.

this is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.


and that's a wrap bestie 🫢 this page came to you courtesy of perl v5.34.0, dated 2022-06-28, from the XML::S...Record(3pm) era of User Contributed Perl Documentation. slay, go process some records, you got this πŸ’…βœ¨

πŸ“¦ where this page comes from