Data::CSel::WrapStruct - Wrap data structure into a tree of objects suitable for use with Data::CSel
This document describes version 0.008 of Data::CSel::WrapStruct (from Perl distribution Data-CSel-WrapStruct), released on 2020-04-15.
use Data::CSel qw(csel); use Data::CSel::WrapStruct qw(wrap_struct unwrap_tree); my $data = [ 0, 1, [2, ["two","dua"], {url=>"http://example.com/two.jpg"}, ["even","prime"]], 3, [4, ["four","empat"], {}, ["even"]], ]; my $tree = wrap_struct($data); my @nodes = csel(":root > * > *:nth-child(4) > *", $tree); my @tags = map { $_->value } @nodes; # -> ("even", "prime", "even")
Scalars are wrapped using Data::CSel::WrapStruct::Scalar class, scalarrefs are wrapped using Data::CSel::WrapStruct::ScalarRef class, arrays are wrapped using Data::CSel::WrapStruct::Array class, and hashes are wrapped using Data::CSel::WrapStruct::Hash class. For convenience, when you load Data::CSel::WrapStruct, it adds Data::CSel::WrapStruct to @Data::CSel::CLASS_PREFIXES so you don't have to specify {class_prefixes=>["Data::CSel::WrapStruct"]} csel() option everytime.
Data::CSel::WrapStruct::Scalar
Data::CSel::WrapStruct::ScalarRef
Data::CSel::WrapStruct::Array
Data::CSel::WrapStruct::Hash
Data::CSel::WrapStruct
@Data::CSel::CLASS_PREFIXES
{class_prefixes=>["Data::CSel::WrapStruct"]}
csel()
my @hashes = map {$_->value} csel("Hash", $tree); # -> ({url=>"http://example.com/two.jpg"}, {})
The wrapper objects provide some methods, e.g.:
my @empty_hashes = map {$_->value} csel("Hash[length=0]", $tree); # -> ({}) my @hashes_that_have_url_key = map {$_->value} csel("Hash[has_key('url')]", $tree); # -> ({url=>"http://example.com/two.jpg"}) my @larger_scalars = [map {$_->value} csel("Scalar[value >= 3]", $tree)] # -> (3, 4)
See "NODE METHODS", "SCALAR NODE METHODS", "SCALARREF NODE METHODS", "ARRAY NODE METHODS", "HASH NODE METHODS" for more details on the provided methods.
You can replace the value of nodes using "value":
my @posint_scalar_nodes = csel("Scalar[value > 0]", $tree); for (@posint_scalar_nodes) { $_->value( $_->value * 10 ) } use Data::Dump; dd unwrap_tree($data); # => [ # 0, # 10, # [20, ["two","dua"], {url=>"http://example.com/two.jpg"}, ["even","prime"]], # 30, # [40, ["four","empat"], {}, ["even"]], # ];
This module provides wrap_struct() which creates a tree of objects from a generic data structure. You can then perform node selection using Data::CSel's csel().
wrap_struct()
You can retrieve the original value of data items by calling value() method on the tree nodes.
value()
Usage:
my $val = $node->value; # get node value $node->value(1); # set node value
Get or set node value.
Note that when setting node value, the new node value is not automatically wrapped for you. If you want to set new node value and expect to select it or part of it again with csel(), you will have to wrap the new value first with "wrap_struct".
$node->remove;
Remove node from parent.
In addition to methods listed in "NODE METHODS", Scalar nodes also have the following methods.
In addition to methods listed in "NODE METHODS", ScalarRef nodes also have the following methods.
In addition to methods listed in "NODE METHODS", Array nodes also have the following methods.
Get array length. Can be used to select an array based on its length, e.g.:
@nodes = csel('Array[length > 0]');
In addition to methods listed in "NODE METHODS", Hash nodes also have the following methods.
Get the number of keys. Can be used to select a hash based on its number of keys, e.g.:
@nodes = csel('Hash[length > 0]');
my $bool = $node->has_key("foo");
Check whether hash has a certain key. Can be used to select a hash, e.g.:
@nodes = csel('Hash[has_key("foo")]');
my $key_val = $node->key("foo");
Get a hash key's value. Can be used to select a hash based on the value of one of its keys, e.g.:
@nodes = csel('Hash[key("name") = "lisa"]');
None exported by default, but exportable.
my $tree = wrap_struct($data);
Wrap a data structure into a tree of objects.
Currently cannot handle recursive structure.
my $data = unwrap_tree($wrapped_data);
Unwrap a tree produced by "wrap_tree" back into unwrapped data structure.
my $data = [0, 1, 2]; my @nodes = csel("Scalar[value > 0]", wrap_struct($data)); for (@nodes) { $_->[0] = "x" } use Data::Dump; dd $data;
still prints [0,1,2] instead of [0,'x','x']. Why?
[0,1,2]
[0,'x','x']
To set node value, you have to use the value() node method with an argument:
... for (@nodes) { $->value("x") } ...
will then print the expected [0,'x','x'].
If you intend to select a data structure with thousands of nodes or more, you're probably better off using other approach, for example Data::Walk::More. Data::Walk::More provides containers for the nodes you're traversing. For example, the CSel expression Hash[has_keys("foo")] > Array > Scalar[value > 0] can be written as:
Hash[has_keys("foo")] > Array > Scalar[value > 0]
walk sub { my $ref = ref $_; return if ref $_; # ... Scalar return if $_ <= 0; # ... [value > 0] return unless ref $Data::Walk::More::containers[-1] eq 'ARRAY'; # ... Array return unless ref $Data::Walk::More::containers[-2] eq 'HASH'; # ... Hash return unless exists $Data::Walk::More::containers[-2]{foo}; # ... [has_keys("foo")] push @matches, $_; }, $data;
Please visit the project's homepage at https://metacpan.org/release/Data-CSel-WrapStruct.
Source repository is at https://github.com/perlancar/perl-Data-CSel-WrapStruct.
Please report any bugs or feature requests on the bugtracker website https://rt.cpan.org/Public/Dist/Display.html?Name=Data-CSel-WrapStruct
When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature.
Data::CSel
perlancar <perlancar@cpan.org>
This software is copyright (c) 2020, 2016 by perlancar@cpan.org.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
To install Data::CSel::WrapStruct, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Data::CSel::WrapStruct
CPAN shell
perl -MCPAN -e shell install Data::CSel::WrapStruct
For more information on module installation, please visit the detailed CPAN module installation guide.