#!/usr/bin/perl -- use strict; use warnings; use HTML::Element; { my $root; my $current; for my $step ( grep length, split '/', q!/html/body/div[@id='wrapper']/div[@id='outer']/div[@id='inner']/div[@id='center']/div[@id='main']/div[2]/table[@id='wrappedcontent']/tbody/tr/td/table/tbody/tr[2]/td[2]!, ) { my ( $tag, $att ) = $step =~ /^([^\[]+)\[?(.*?)\]?$/; warn "step($step)tag($tag)att($att) \n"; if ( $current and $root ) { if ( $att =~ /^\d+$/ ) { my $new; for my $n ( 1 .. $att ) { $new = HTML::Element->new($tag, ncount => $n ); $current->push_content($new); } $current = $new; } elsif( $att =~/\@(\w+)(?:[^=]*=['"]*([^'"]+)['"]*)?$/ ) { my $new = HTML::Element->new($tag, $1 => $2 ); $current->push_content($new); $current = $new; } else { my $new = HTML::Element->new($tag); $current->push_content($new); $current = $new; } } else { $root = HTML::Element->new( $tag ); $current = $root; } } undef $current; print $root->as_HTML( '><&' => " " ); $root->delete; undef $root; } __END__ step(html)tag(html)att() step(body)tag(body)att() step(div[@id='wrapper'])tag(div)att(@id='wrapper') step(div[@id='outer'])tag(div)att(@id='outer') step(div[@id='inner'])tag(div)att(@id='inner') step(div[@id='center'])tag(div)att(@id='center') step(div[@id='main'])tag(div)att(@id='main') step(div[2])tag(div)att(2) step(table[@id='wrappedcontent'])tag(table)att(@id='wrappedcontent') step(tbody)tag(tbody)att() step(tr)tag(tr)att() step(td)tag(td)att() step(table)tag(table)att() step(tbody)tag(tbody)att() step(tr[2])tag(tr)att(2) step(td[2])tag(td)att(2)