<?xml version="1.0" encoding="windows-1252"?>
<node id="74867" title="Opera Bookmarks to XBEL" created="2001-04-23 20:31:02" updated="2005-08-11 05:57:22">
<type id="1748">
sourcecode</type>
<author id="16834">
OeufMayo</author>
<data>
<field name="doctext">
&lt;code&gt;#!/usr/bin/perl -w
use strict;
use XML::Writer;

# Small utility to parse Opera bookmark files.
# Originally written in Python by Lars Marius Garshol
# perl version - Briac Pilpré

my $version = &lt;&gt;;
die "Doesn't seem to be a Opera Hotlist\n" if $version !~ /^Opera/;

chomp( $version );

my $xml = new XML::Writer(DATA_MODE=&gt;1, DATA_INDENT=&gt;1);
   $xml-&gt;xmlDecl();
   $xml-&gt;doctype(
       'xbel',
       '+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML',
       'xbel.dtd');
   $xml-&gt;startTag('xbel');
   $xml-&gt;dataElement('desc', $version);

while (&lt;&gt;){
        next unless /\S/;
        chomp;
        if ( $_ eq '#FOLDER' || $_ eq '#URL' ){
                my $node = $_;

                my $line;
                {
                        local $/ = "";  # Paragraph mode
                        $line    = &lt;&gt;;
                }

                if ($node eq '#FOLDER'){
                        my $name    = $1 if $line =~ /NAME=(.*)/;
                        my $created = $1 if $line =~ /CREATED=(.*)/;
                        $xml-&gt;startTag('folder');
                        $xml-&gt;dataElement('title', $name);
                }

                elsif ($node eq '#URL') {
                        my $name    = $1 if $line =~ /NAME=(.*)/;
                        my $created = $1 if $line =~ /CREATED=(.*)/;
                        my $order   = $1 if $line =~ /ORDER=(.*)/;
                        my $visited = $1 if $line =~ /VISITED=(.*)/;
                        my $url     = $1 if $line =~ /URL=(.*)/;

                        $xml-&gt;startTag('bookmark', href =&gt; $url, 
                            added =&gt; $created, visited =&gt; $visited);
                        $xml-&gt;dataElement('title', $name);
                        $xml-&gt;endTag('bookmark');
                }

        }
        elsif ( $_ eq '-'){
                $xml-&gt;endTag('folder');
        }
}

$xml-&gt;endTag('xbel');
&lt;/code&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;b&gt;Bonus&lt;/b&gt;: Added Bonus the xbel2adr script!&lt;/p&gt;
&lt;code&gt;__END__
#!/usr/bin/perl -w
use strict;
use XML::Parser;
die "usage: $0 opera.xbel\n" if !$ARGV[0];
my $parser = new XML::Parser(Handlers =&gt; {
	Start=&gt;\&amp;start, End=&gt;\&amp;end, Char=&gt;\&amp;char,
});
my%equiv=(title=&gt;'NAME', desc=&gt;'DESCRIPTION');
my $flag = '';
$parser-&gt;parsefile($ARGV[0]);
sub char {
	my ($p, $txt) = @_; return if $txt =~ /^\s*$/;
      chomp($txt);
	print $txt . "\n" if exists($equiv{$flag});
}
sub start {
	my ($p, $e, %a) = @_; $flag = $e;
	if    ($e eq 'folder'){  print "\n#FOLDER\n" }
	elsif ($e eq 'bookmark'){print "\n#URL\n\tURL=" . $a{'href'} if $a{'href'}}
	else  {print "\n\t" . $equiv{$e} . "=" if exists $equiv{$e}	}
}
sub end {undef $flag}
&lt;/code&gt;
&lt;hr /&gt;
&lt;p&gt;Previous version:&lt;/p&gt;
&lt;code&gt;__END__
#!/usr/bin/perl -w
#
# adr2xbel : Convert Opera Bookmarks file to xbel
#            (XML Bookmark Exchange Language)
# OeufMayo - 23 apr 2001

use strict;
use XML::Writer;
use IO;
die "usage: $0 opera.adr\n" if !$ARGV[0];
my $output = new IO::File("&gt; $ARGV[0].xbel.xml") or die $!;
my $writer = new XML::Writer(OUTPUT =&gt; $output, 
                             DATA_MODE =&gt; 1,
				     DATA_INDENT =&gt; 4) or die $!;
$writer-&gt;xmlDecl('iso-8859-1', 'no');
$writer-&gt;doctype(
           'xbel',
           undef,
           'http://www.python.org/topics/xml/dtds/xbel-1.0.dtd');
$writer-&gt;startTag('xbel');
$writer-&gt;dataElement('title', 'Opera Hotlist version 2.0');

$/ = "";
while (&lt;&gt;){
	chomp;
	my @chunk = split(/\n\t/, $_);
	
	while ($chunk[0] =~ s/^(-\n)//){	# Folder end
		$writer-&gt;endTag('folder') if $chunk[0];
	}

	if    ($chunk[0] =~ /^#FOLDER/){	# Folder beginning
		shift @chunk;
		my %attrs = &amp;getAttlist(@chunk);
		$writer-&gt;startTag("folder");
		for ('title', 'desc'){
			$writer-&gt;dataElement($_, $attrs{$_});
		}
	}
	
	elsif ($chunk[0] =~ /^#URL/){		# URL Tag
		shift @chunk;
		my %attrs = &amp;getAttlist(@chunk);
		$writer-&gt;startTag("bookmark", 
                              'href' =&gt; $attrs{href} );
			for ('title', 'desc'){
				$writer-&gt;dataElement($_, $attrs{$_});
			}
		$writer-&gt;endTag("bookmark");
	}
}

$writer-&gt;endTag('xbel');
$writer-&gt;end;

#########################

sub getAttlist {
	my %attrs;
	my %tr = (
            URL=&gt;'href',
            DESCRIPTION=&gt;'desc',
            NAME=&gt;'title',
      );
	foreach $_ (@_){
		m/^([^=]+)=(.*)$/;
		my ($key, $value) = ($1, $2);
		next unless (
                   $key eq 'URL'         || 
                   $key eq 'DESCRIPTION' || 
                   $key eq 'NAME'
            );
		$key = $tr{$key};
		$attrs{$key} = $value;
	}
	return %attrs;
}

&lt;/code&gt;</field>
<field name="codedescription">
The python guys (they can't be all bad, after all :) have created a DTD called [http://pyxml.sourceforge.net/topics/xbel/|XML Bookmark Exchange Language] which "&lt;i&gt;is a rich interchange
format for "bookmark" data as used by most Internet browsers.&lt;/i&gt;"
As I wanted to play with the [cpan://XML::Writer] module and  clean up my bookmark files, I ended up whipping up this code. Have fun!
&lt;p&gt;&lt;b&gt;Update 2001-11-13&lt;/b&gt;: Complete rewrite of the adr2xbel script. It follows a bit more closely the python script found in the PyXML library demos.&lt;/p&gt;</field>
<field name="codecategory">
Web Stuff</field>
<field name="codeauthor">
Briac '[Oeufmayo]' Pilpr&amp;eacute;</field>
</data>
</node>
