use strict;
#use warnings;
package RDF::Notation3::Template::TXML;
require 5.005_62;
use RDF::Notation3;
############################################################
@RDF::Notation3::Template::TXML::ISA = qw(RDF::Notation3);
sub _process_statement {
my ($self, $subject, $properties) = @_;
$subject = $self->_expand_prefix($subject);
$subject =~ s/^<(.*)>$/$1/;
my $prev;
my $j = 0;
foreach (@$properties) {
if ($_->[0] ne 'i') {
if ($j == 0 or $prev eq 'i') {
my @attr = ();
# nodeID is used for blank nodes
if ($subject =~ /^$self->{ansuri}(.*)$/) {
push @attr, ['rdf:nodeID' => "$self->{nIDpref}$1"];
} else {
push @attr, ['rdf:about' => $subject];
}
$self->doStartElement('rdf:Description', \@attr);
}
my ($attr, $pred) = $self->_process_predicate($_->[0]);
$pred =~ s/^:(.*)$/$1/;
for (my $i = 1; $i < scalar @$_; $i++) {
$_->[$i] = $self->_expand_prefix($_->[$i]);
my @attr = @$attr;
my $val = '';
# URI
if ($_->[$i] =~ s/^<(.*)>$/$1/) {
# nodeID is used for blank nodes
if ($_->[$i] =~ /^$self->{ansuri}(.*)$/) {
push @attr, ['rdf:nodeID' => "$self->{nIDpref}$1"];
} else {
push @attr, ['rdf:resource' => $_->[$i]];
}
# string2
} elsif ($_->[$i] =~ s/^"""(.*)"""$/$1/s) {
$val = $_->[$i];
# string1
} elsif ($_->[$i] =~ s/^"(.*)"$/$1/) {
$val = $_->[$i];
} else {
$self->_do_error(402, $_->[$i]);
}
# # URI
# $_->[$i] =~ s/^<(.*)>$/$1/ and
# push @attr, ['rdf:resource' => $_->[$i]];
# # string2
# $_->[$i] =~ s/^"""(.*)"""$/$1/s and
# $val = $_->[$i];
# # string1
# $_->[$i] =~ s/^"(.*)"$/$1/ and
# $val = $_->[$i];
# escaping literals
$val =~ s/</</g;
$val =~ s/>/>/g;
$val =~ s/&/&/g;
$self->doElement($pred, \@attr, $val);
$self->{count}++;
}
if ($j == scalar @$properties - 1 or
($properties->[$j+1]->[0] eq 'i')) {
$self->doEndElement('rdf:Description');
}
} else {
# inverse mode (is, <-)
for (my $i=2; $i < scalar @$_; $i++) {
$_->[$i] = $self->_expand_prefix($_->[$i]);
$_->[$i] =~ s/^<(.*)>$/$1/;
my @attr = ();
push @attr, [about => $_->[$i]];
$self->doStartElement('rdf:Description', \@attr);
my ($attr, $pred) = $self->_process_predicate($_->[1]);
my @attr2 = @$attr;
$pred =~ s/^:(.*)$/$1/;
push @attr2, ['rdf:resource' => $subject];
$self->doElement($pred, \@attr2, '');
$self->{count}++;
$self->doEndElement('rdf:Description');
}
}
$prev = $_->[0];
$j++;
}
}
sub _expand_prefix {
my ($self, $qname) = @_;
foreach (keys %{$self->{ns}->{$self->{context}}}) {
$qname =~ s/^$_:(.*)$/<$self->{ns}->{$self->{context}}->{$_}$1>/;
}
if ($qname =~ /^([_a-zA-Z]\w*)*:[a-zA-Z]\w*$/) {
$self->_do_error(106, $qname);
}
return $qname;
}
sub _process_predicate {
my ($self, $name) = @_;
my @attr = ();
my $p = '';
my $pushed = 0;
if ($name =~ /^([_a-zA-Z]\w*)*:[a-zA-Z]\w*$/) {
$p = $1;
} else { # not a QName - must be turned to QName
my $qnamed = 0;
# checking if the NS already exists
foreach (keys %{$self->{ns}->{$self->{context}}}) {
my $ns = _escape_ns($self->{ns}->{$self->{context}}->{$_});
if ($name =~ s/^<$ns([a-zA-Z]\w*)>$/$_:$1/) {
$qnamed = 1;
$p = $_;
last;
}
}
# checking out hard-coded NS
unless ($qnamed) {
foreach (keys %{$self->{hardns}}) {
my $ns = _escape_ns($self->{hardns}->{$_}->[1]);
if ($name =~ s/^<$ns([a-zA-Z]\w*)>$/$self->{hardns}->{$_}->[0]:$1/) {
$p = $self->{hardns}->{$_}->[0];
$self->{ns}->{$self->{context}}->{$p} =
$self->{hardns}->{$_}->[1];
$qnamed = 1;
$p = $self->{hardns}->{$_}->[0];
last;
}
}
}
# inventing new NS
unless ($qnamed) {
my $i = 1;
my $pref = 'pref';
while ($self->{ns}->{$self->{context}}->{$pref}) {
$pref = "$pref$i";
$i++;
}
if ($name =~ s/^<(.*?)([a-zA-Z]\w*)>$/$pref:$2/) {
push @attr, ["xmlns:$pref" => $1];
$qnamed = 1;
$pushed = 1;
}
}
$self->_do_error(401, $name) unless $qnamed;
}
unless ($pushed) {
if ($p) {
push @attr, ["xmlns:$p" => $self->{ns}->{$self->{context}}->{$p}];
$self->_do_error(106, $name)
unless $self->{ns}->{$self->{context}}->{$p};
} else {
push @attr, ["xmlns" => $self->{ns}->{$self->{context}}->{''}];
$self->_do_error(106, $name)
unless $self->{ns}->{$self->{context}}->{''};
}
}
return (\@attr, $name);
}
sub _escape_ns {
my $ns = shift;
$ns =~ s/\+/\\+/;
$ns =~ s/\*/\\*/;
$ns =~ s/\?/\\?/;
return $ns;
}
1;
__END__
# Below is a documentation.
=head1 NAME
RDF::Notation3::Template::TXML - an RDF/XML converter template
=head1 LICENSING
Copyright (c) 2001 Ginger Alliance. All rights reserved. This program is free
software; you can redistribute it and/or modify it under the same terms as
Perl itself.
=head1 AUTHOR
Petr Cimprich, petr@gingerall.cz
=head1 SEE ALSO
perl(1), RDF::Notation3.
=cut