| XML-DTD documentation | Contained in the XML-DTD distribution. |
XML::DTD::EntityManager - Perl module for managing entity declarations in a DTD
use XML::DTD::EntityManager; my $em = XML::DTD::EntityManager->new;
XML::DTD::EntityManager is a Perl module for managing entity declarations in a DTD. The following methods are provided.
my $em = XML::DTD::EntityManager->new;
Construct a new XML::DTD::EntityManager object.
if (XML::DTD::EntityManager->isa($obj) {
...
}
Test object type.
my $ent = XML::DTD::Entity->new('<!ENTITY a "b">');
$em->insert($ent);
Insert an entity declaration. This method is a wrapper which determines the type of entity and calls insertpe or insertge as appropriate.
my $ent = XML::DTD::Entity->new('<!ENTITY % a "b">');
$em->insertpe($ent);
Insert a parameter entity declaration.
my $val = $em->pevalue('%a;');
Lookup a parameter entity value. Recursively expands internal parameter and character entity references. Leaves general entity references unmodified.
May also be called as:
my $val = $em->pevalue('a');
with the same effect.
my $ent = XML::DTD::Entity->new('<!ENTITY a "b">');
$em->insertge($ent);
Insert a general entity declaration.
my $val = $em->gevalue('&a;');
Lookup a general entity value.
May also be called as:
my $val = $em->gevalue('a');
with the same effect.
my $txt = $em->cevalue('<');
Convert a character entity declaration. The example returns the
character <.
May also be called as:
my $val = $em->peexpand('x3c');
with the same effect.
my $val = $em->peexpand('%a;');
Lookup a parameter entity declaration and return its expansion as in pevalue if it exists, otherwise return the peref.
May also be called as:
my $val = $em->peexpand('a');
with the same effect. Note: returns %a; if there is no definition
of a, even if called in this form.
my $txt = $em->entitysubst('abc &a; def');
Perform entity substitution in text. Recursively expands internal parameter and character entity references. Leaves general entity references unmodified.
For details see sections 4.4 XML Processor Treatment of Entities and References (http://www.w3.org/TR/2006/REC-xml-20060816/#entproc) and 4.5 Construction of Entity Replacement Text (http://www.w3.org/TR/2006/REC-xml-20060816/#intern-replacement) in Extensible Markup Language (XML) 1.0 (Fourth Edition) (http://www.w3.org/TR/2006/REC-xml-20060816/)
Brendt Wohlberg <wohl@cpan.org>
Copyright (C) 2004-2010 by Brendt Wohlberg
This library is available under the terms of the GNU General Public License (GPL), described in the GPL file included in this distribution.
Peter Lamb <Peter.Lamb@csiro.au> added fetching of external entities and improved entity substitution.
| XML-DTD documentation | Contained in the XML-DTD distribution. |
package XML::DTD::EntityManager; use XML::DTD::Error; use 5.008; use strict; use warnings; our @ISA = qw(); our $VERSION = '0.09'; # Constructor sub new { my $arg = shift; my $ent = shift; my $cls = ref($arg) || $arg; my $obj = ref($arg) && $arg; my $self; if ($obj) { # Called as a copy constructor $self = { %$obj }; } else { # Called as the main constructor $self = { }; $self->{'PARAMETER'} = { }; $self->{'GENERAL'} = { }; } bless $self, $cls; return $self; } # Determine whether object is of this type sub isa { my $cls = shift; my $r = shift; if (defined($r) && ref($r) eq $cls) { return 1; } else { return 0; } } # Insert an entity sub insert { my $self = shift; my $ent = shift; if ($ent->isparam) { $self->insertpe($ent); } else { $self->insertge($ent); } } # Insert a parameter entity declaration sub insertpe { my $self = shift; my $pe = shift; my $name = $pe->name; if (defined($self->{'PARAMETER'}->{$name})) { return 0; } else { $self->{'PARAMETER'}->{$name} = $pe; return 1; } } # Lookup a parameter entity declaration sub pevalue { my $self = shift; my $peref = shift; $peref = $1 if ($peref =~ /^%(.+);$/); my $ent = $self->{'PARAMETER'}->{$peref}; if (defined $ent) { if ($ent->isextern) { # The value of an external entity is just itself return $ent->value; } else { # The value of an internal entity has character and # parameter entity expansion carried out on it return $self->entitysubst($ent->value); } } else { return undef; } } # Lookup a parameter entity declaration and return # its expansion, otherwise return the peref sub peexpand { my $self = shift; my $peref = shift; my $peval = $self->pevalue($peref); if (defined $peval) { $peref = $peval; } else { $peref = '%'.$peref.';'; } return $peref; } # Lookup a parameter entity's containing URI sub peuri { my $self = shift; my $peref = shift; $peref = $1 if ($peref =~ /^%(.+);$/); my $ent = $self->{'PARAMETER'}->{$peref}; if (defined $ent) { return $ent->uri; } else { return undef; } } # Insert a general entity declaration sub insertge { my $self = shift; my $ge = shift; my $name = $ge->name; if (defined($self->{'GENERAL'}->{$name})) { return 0; } else { $self->{'GENERAL'}->{$name} = $ge; return 1; } } # Lookup a general entity declaration sub gevalue { my $self = shift; my $geref = shift; $geref = $1 if ($geref =~ /^\&(.+);$/); my $ent = $self->{'GENERAL'}->{$geref}; if (defined $ent) { return $ent->value; } else { return undef; } } # Convert a character entity declaration sub cevalue { my $self = shift; my $ceref = shift; $ceref = $1 if ($ceref =~ /^\&#(.+);$/); if ($ceref =~ /^x([0-9a-fA-F]+)$/) { return chr hex $1; } elsif ($ceref =~ /^[0-9]+$/) { return chr $ceref; } else { return undef; } } # Perform entity substitution in text sub entitysubst { my $self = shift; my $txt = shift; my $gesf = shift; # Flag selecting substitution of general entity refs my $lt = ''; my $rt = $txt; while($rt =~ /(?:(%|\&)([\w\.:\-_]+)|(?:\&#(([0-9]+)|(x[0-9a-fA-F]+))));/) { $rt = $'; $lt .= $`; my ($type, $val); my $entv; if (defined $1) { # Entity ref or parameter ref ($type, $val) = ($1, $2); if ($type eq '%') { # Substitute parameter refs $entv = $self->pevalue($type.$val.';'); } else { if ($gesf) { $entv = $self->gevalue($type.$val.';'); } else { # Bypass entity ref $entv = $type.$val.';'; } } } else { # Character ref ($type, $val) = ('&', '#'.$3); $entv = $self->cevalue($type.$val.';'); } if (defined $entv) { $lt .= $entv; } else { $lt .= $type.$val.';'; throw XML::DTD::Error("Reference to undefined entity in string: $txt", $self); } } $lt .= $rt; return $lt; } # Perform entity substitution in text sub includeaspe { my $self = shift; my $txt = shift; my $lt = ''; my $rt = $txt; while($rt =~ /(%[\w\.:\-_]+;)/) { $rt = $'; $lt .= $`; my $entv; if (defined $1) { # Substitute parameter ref $entv = $self->pevalue($1); } if (defined $entv) { $lt .= ' '.$entv.' '; } else { $lt .= $1; throw XML::DTD::Error("Reference to undefined entity in string: $txt", $self); } } $lt .= $rt; return $lt; } 1; __END__