XML-STX
view release on metacpan or search on metacpan
STX/STXPath.pm view on Meta::CPAN
sub nodeNameTest {
my ($self, $nodes) = @_;
#$self->{tokens}->[0] || ($self->{tokens}->[0] = '');
#print "EXP: nodeNameTest ", $self->{tokens}->[0], "\n";
my $res_nodes = [];
# child axis
if ($self->{axis} == 1) {
foreach (@$nodes) {
# frame exists
if (@{$self->{STX}->{Stack}} > $_->{Index}+1) {
my $node = $self->{STX}->{Stack}->[$_->{Index}+1];
my $res = $self->_node_match($node);
push @$res_nodes, $res if $res != -1;
}
}
# descendant axis
} elsif ($self->{axis} == 2) {
foreach (@$nodes) {
# scan all descendants
for (my $i = $_->{Index}+1; $i < @{$self->{STX}->{Stack}}; $i++) {
my $node = $self->{STX}->{Stack}->[$i];
my $res = $self->_node_match($node);
push @$res_nodes, $res if $res != -1;
}
}
}
shift @{$self->{tokens}};
return $res_nodes;
}
sub attributeNameTest {
my ($self, $nodes) = @_;
#print "EXP: attributeNameTest ", $self->{tokens}->[0], "\n";
my $res_nodes = [];
foreach (@{$nodes}) {
my $res = $self->_attribute_match($_->{Index});
push @$res_nodes, @$res;
}
shift @{$self->{tokens}};
#print "EXP: attributeNameTest ",join(':',map($_->{Name},@$res_nodes)),"\n";
# nodes are turned to a sequence
my @seq = map([$_,STX_NODE], @$res_nodes);
return \@seq;
}
sub namespaces {
my ($self, $node) = @_;
#print "EXP: namespaces ", $self->{tokens}->[0], "\n";
my $ns_nodes = [];
my $pref = $self->{tokens}->[0];
if ($node->{Type} == 1) {
my @prefs = $pref eq '*' ? $self->{STX}->{ns}->get_prefixes
: ($self->{tokens}->[0]);
foreach (@prefs) {
my $p = $_ eq '' ? '#default' : $_;
my $uri = $self->{STX}->{ns}->get_uri($p);
my $node = {Type => 8,
Index => scalar @{$self->{STX}->{Stack}} + 1,
Name => $p,
Value => $uri,
};
#print "EXP: NS node $p|$uri\n";
push @$ns_nodes, $node;
}
} else {
$self->doError(17, 3, $node->{Type});
}
return $ns_nodes;
}
# ==================================================
# Match Pattern
# pathPattern
sub matchPath {
my ($self, $node, $path) = @_;
my $i = $#$path;
#print "EXP: matchPath $i\n";
my $result = 1;
while ($i >= 0 and $result) {
my $step = $path->[$i];
#print "EXP: matchPath->$i $step->{left}:$#{$step->{step}}\n";
#print "EXP: matchPath->$i node $node->{Index}\n";
# to handle '/' pattern
if ($#{$step->{step}} == -1 && $step->{left} eq 'R') {
#print "EXP: '/' pattern, node: $node->{Type}\n";
if ($node->{Type} == STX_ROOT_NODE) {
return 1;
} else {
return 0;
}
}
$result = $self->matchStep($node, $step->{step});
#print "EXP: matchPath->$i <$result>\n";
return 0 unless $result;
if ($step->{left} eq 'P') {
#print "EXP: matchPath->$i process parent\n";
$node = $self->{STX}->{Stack}->[$node->{Index}-1];
} elsif ($step->{left} eq 'R') {
#print "EXP: matchPath->$i verify root\n";
return $node->{Index} == 1 ? $result : 0;
} elsif ($step->{left} eq 'A') {
#print "EXP: matchPath->$i process ancestors\n";
my $a_result = 0;
foreach (my $j = $node->{Index} - 1; $j >= 0; $j--) {
( run in 0.671 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )