summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changes1
-rw-r--r--lib/PPIx/XPath.pm59
2 files changed, 55 insertions, 5 deletions
diff --git a/Changes b/Changes
index 7f70ed9..ae0d039 100644
--- a/Changes
+++ b/Changes
@@ -1,3 +1,4 @@
{{$NEXT}}
- fixed example code as per RT#116737, thanks Alastair Cooke
+ - more documentation
- switched to Dist::Zilla
diff --git a/lib/PPIx/XPath.pm b/lib/PPIx/XPath.pm
index 4853fe6..a4e7609 100644
--- a/lib/PPIx/XPath.pm
+++ b/lib/PPIx/XPath.pm
@@ -57,6 +57,15 @@ initial C<PPI::>, with C<::> replaced by C<->. That is:
=end :list
+=method C<new>
+
+ my $pxp = PPIx::XPath->new("some_code.pl");
+
+ my $pxp = PPIx::XPath->new($pdom);
+
+Only useful for the backward-compatible, and deprecated, interface.
+Returns an instance of C<PPIx::XPath> tied to the given document.
+
=cut
sub new {
@@ -80,9 +89,22 @@ sub new {
return bless {doc=>$doc},$class;
}
-# PPIx::XPath 1.0.0 allowed the use of partial package names as node names;
-# this collides with the axis specification of proper XPath.
-# Here we change the "old-style" node names into the new names
+=method C<clean_xpath_expr>
+
+ my $new_xpath_expr = $pxp->clean_xpath_expr($old_xpath_expr);
+
+C<PPIx::XPath> version 1.0.0 allowed the use of partial package names
+(like C<Token::Number>) as element names: this collides with the axis
+specification of proper XPath. For this reason, in newer version of
+C<PPIx::XPath>, the element name is the class name of the PDOM node,
+minus the initial C<PPI::>, with C<::> replaced by C<-> (like
+C<Token-Number>).
+
+This method replaces all occurrences of PPI package names in the given
+string with the new names.
+
+=cut
+
{
my $legacy_names_rx;my %new_name_for;
sub clean_xpath_expr {
@@ -95,6 +117,7 @@ sub new {
my @PPI_Packs;
# taken from Devel::Symdump
+ # breadth-first search of packages under C<PPI>
my @packages=('PPI');
while (my $pack=shift(@packages)) {
my %pack_symbols = do {
@@ -102,15 +125,20 @@ sub new {
%{*{"$pack\::"}}
};
while (my ($key,$val)=each(%pack_symbols)) {
+ # that {HASH} lookup is special for typeglobs, so we have
+ # to alias a local typeglob to make it work
local *ENTRY=$val;
+ # does this symbol table entry look like a sub-package?
if (defined $val && defined *ENTRY{HASH} && $key=~/::$/
&& $key !~ /^::/
&& $key ne 'main::' && $key ne '<none>::') {
+ # add it to the search list
my $p = "$pack\::$key";$p =~ s{::$}{};
push @packages,$p;
- $p =~ s{^PPI::}{};
+ # and add it to the map of names
+ $p =~ s{^PPI::}{};
next unless $p=~/::/;
my $newname=$p;
@@ -120,12 +148,34 @@ sub new {
}
}
}
+
+ # @PPI_Packs now contains all the old-style names, build a regex
+ # to match them (the sort is important, we want to match longer
+ # names first!)
$legacy_names_rx='\b('.join(q{|},
sort {length($b) <=> length($a)} @PPI_Packs
).')\b';
$legacy_names_rx=qr{$legacy_names_rx};
}
+=method C<match>
+
+ my @subs = $pxp->match("//Statement::Sub");
+ my $vars = $pxp->match("//Token::Symbol");
+
+Only useful for the backward-compatible, and deprecated,
+interface. From the document this instance was built against, returns
+the nodes that match the given XPath expression.
+
+You should not use this method, you should call L<<
+C<findnodes>|Tree::XPathEngine/findnodes >> instead:
+
+ my $xpath = Tree::XPathEngine->new();
+ my @subs = $xpath->findnodes('//Statement-Sub',$pdom);
+ my @vars = $xpath->findnodes('//Token-Symbol',$pdom);
+
+=cut
+
sub match {
my ($self,$expr) = @_;
@@ -134,7 +184,6 @@ sub match {
Tree::XPathEngine->new()->findnodes($expr,$self->{doc});
}
-
=head1 BUGS and LIMITATIONS
=for :list