NAME

XML::Chain::Selector - selector for traversing the XML::Chain

SYNOPSIS

my $user = xc('user', xmlns => 'testns')
            ->auto_indent({chars=>' 'x4})
            ->a(xc('name')->t('Johnny Thinker'))
            ->a(xc('username')->t('jt'))
            ->c('bio')
                ->a(xc('div', xmlns => 'http://www.w3.org/1999/xhtml')
                    ->a(xc('h1')->t('about'))
                    ->a(xc('p')->t('...')))
                ->a(xc('greeting')->t('Hey'))
                ->up;
say $user->as_string;

Will print:

<user xmlns="testns">
    <name>Johnny Thinker</name>
    <username>jt</username>
    <bio>
        <div xmlns="http://www.w3.org/1999/xhtml">
            <h1>about</h1>
            <p>...</p>
        </div>
        <greeting>Hey</greeting>
    </bio>
</user>

DESCRIPTION

CHAINED METHODS

c, append_and_select

Appends new element to current elements and changes context to them. New element is defined in parameters:

$xc->c('i', class => 'icon-download icon-white')
# <i class="icon-download icon-white"/>

First parameter is name of the element, then followed by optional element attributes.

t, append_text

Appends text to current elements.

xc('span')->t('some')->t(' ')->t('more text')
# <span>some more text</span>

First parameter is name of the element, then followed by optional element attributes.

root

Sets document element as current element.

say xc('p')
    ->t('this ')
    ->a(xc('b')->t('is'))
    ->t(' important!')
    ->root->as_string;
# <p>this <b>is</b> important!</p>

up, parent

Traverse current elements and replace them by their parents.

find

say $xc->find('//p/b[@class="less"]')->text_content;

Look-up elements by xpath and set them as current elements.

children

Set all current elements child nodes as current elements.

first

Set first current elements as current elements.

empty

Removes all child nodes from current elements.

rename

my $body = xc('bodyz')->rename('body');
# <body/>

Rename node name(s).

each

# rename using each
$body->rename('body');
$body
    ->a(xc('p.1')->t(1))
    ->a(xc('p.2')->t(2))
    ->a(xc('div')->t(3))
    ->a(xc('p.3')->t(4))
    ->each(sub { $_->rename('p') if $_->name =~ m/^p[.]/ });
is($body, '<body><p>1</p><p>2</p><div>3</div><p>4</p></body>','rename using each()');

Loops through all selected elements and calls callback for each of them.

remap

xc('body')->a('p', i => 1)->children->remap(
    sub {
        (map {xc('e', i => $_)} 1 .. 3), $_;
    }
)->root;
# <body><e i="1"/><e i="2"/><e i="3"/><p i="1"/></body>

Replaces all selected elements by callback returned elements.

rm, remove_and_parent

my $pdiv = xc('base')
        ->a(xc('p')->t(1))
        ->a(xc('p')->t(2))
        ->a(xc('div')->t(3))
        ->a(xc('p')->t(4));
my $p = $pdiv->find('//p');
# $pdiv->find('//p[position()=3]')->rm->name eq 'base'
# $p->count == 2     # deleted elements are skipped also in old selectors
# <base><p>1</p><p>2</p><div>3</div></base>

Deletes current elements and returnes their parent.

auto_indent

my $simple = xc('div')
                ->auto_indent(1)
                ->c('div')->t('in')
                ->root;
say $simple->as_string;

Will print:

<div>
    <div>in</div>
</div>

Turn on/off tidy/auto-indentation of document elements. Default indentation characters are tabs.

Argument can be either true/false scalar or a hashref with indentation options. Currently {chars=' 'x4} > will set indentation characters to be four spaces.

NOTE Currently works only on element on which as_string() is called using HTML::Tidy. In the future it is planned to be possible to set indentation on/off also for nested elements. For example not to indent embedded html elements.

WARNING HTML::Tidy has a circular reference and leaks memory when used. Better don't use auto_indent() at in this version in persistent environments.

CHAINED DOCUMENT METHODS

See "CHAINED DOCUMENT METHODS" in XML::Chain.

METHODS

as_string, toString

Returns string representation of current XML elements. Call root before to get a string representing the whole document.

$xc->as_string
$xc->root->as_string

as_xml_libxml

Returns array of current elements as XML::LibXML objects.

text_content

Returns text content of all current XML elements.

count / size

say $xc->find('//b')->count;

Return the number of current elements.

single

my $lxml_el = $xc->find('//b')->first->as_xml_libxml;

Checks is there is exactly one element in current elements and return it as XML::Chain::Element object.

AUTHOR

Jozef Kutej

COPYRIGHT & LICENSE

Copyright 2017 Jozef Kutej, all rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.