einführung in perl - techfak.uni-bielefeld.de · xml Œ extensible markup language ist ... Œ...

28
Einführung in Perl WWW, Teil 2: XML Jörn Clausen Georg Fuellen

Upload: dinhduong

Post on 04-Jun-2018

218 views

Category:

Documents


0 download

TRANSCRIPT

Einführung in Perl

WWW, Teil 2: XML

Jörn Clausen Georg Fuellen

Übersicht

• XML: eXtensible Markup Language

• XML parsen:

– XML::Parser

– SAX: Simple API for XML

– DOM: Document Object Model

– XPath

• XML erzeugen

die Ursprünge von XML

• HTML Markupsprache für das WWW

• Mischung aus Struktur- und Layout-Information

• proprietäre Erweiterungen, „Mißbrauch“ von tags

• Informationen in HTML-Seiten „verschüttet“

• Lösung: Markup den Anforderungen anpassen

• Standard Generalized Markup Language (SGML) zu kompliziert

• XML: 1996/97 entwickelt, 1998 erste Recommendation des W3C

• inzwischen: zahlreiche Standards im XML-Umfeld

XML – eXtensible Markup Language

• ist . . .

– keine Markupsprache

– nicht HTML++, sondern SGML−−

– kein Allheilmittel, trotz des Hypes

• ist aber auch . . .

– einfach zu erlernen

– weithin akzeptiert

– durch viele Implementierungen etabliert

ein Beispiel

<?xml version="1.0"?>

<library>

<book edition="3rd" year="2000">

<title>Programming Perl</title>

<author>Larry Wall</author>

<author>Tom Christiansen</author>

<author>Jon Orwant</author>

</book>

<book year="1998">

<title>Advanced Perl Programming</title>

<author>Sriram Srinivasan</author>

</book>

</library>

Aufbau von XML: Elemente

• öffnendes und schließendes tag:

<item>XML is not a ...</item>

• keine Minimierungsregeln

• leeres Inhaltsmodell:

<hr/> statt <hr></hr> statt <hr>

• Schachtelung muß „passen“: well-formed

Aufbau von XML: Attribute

• Zusatzinformationen zu Elementen

<book year="2000"> ... </book>

• Attribute im öffnenden tag

• Design-Frage: Wann Element, wann Attribut?

<date y="2001" m="7" d="9"/>

vs.

<date><y>2001</y><m>7</m><d>9</d></date>

Aufbau von XML: Entitäten

• Makros und Sonderzeichen

• in XML vordefiniert: &amp; &lt; &gt; &apos; &quot;

• weitere müssen definiert werden

• XML verwendet Unicode

Verwendung von XML

• Texte/Daten können ad-hoc kodiert werden

• stand-alone Dokument

• formale Grammatik: Document Type Definition (DTD)

• weitere Grammatik-Sprachen: XML-Schema, RELAX NG, . . .

• Dokument validiert

Verarbeitung von XML

• zwei Verfahren:

– event-basiert

– Baumstruktur

• Speicherplatz vs. freier Zugriff

• Geschwindigkeit vs. startup-Zeit

• stream-Fähigkeit

XML::Parser

• verwendet expat

• ist Grundlage für fast alle weiteren XML-Module

• handler für events, u.a.:

– Init, Final

– Start, End

– Char, . . .

• handler ist Subroutine, erhält geeignete Parameter

XML::Parser, cont.use XML::Parser;

my $parser = XML::Parser->new(

Handlers => { Start => \&start_h,

End => \&end_h,

Char => \&char_h });

$parser->parsefile(’library.xml’);

sub start_h {

my ($parser, $elem, @attr) = @_;

print "found $elem\n";

for (; $key=shift(@attr), $val=shift(@attr); ) {

print " $key --> $val\n";

}

}

SAX – The Simple API for XML

• Java-API

• events:

– start_document, end_document, start_element,

end_element, characters, . . .

• Trennung in Parser-Modul und Handler-Modul

• verschiedene SAX-Parser:

– XML::Parser::PerlSAX

– XML::SAX::Expat, XML::LibXML::SAX::Parser, . . .

• Parser-Factory

• Basis-Klasse für Handler: XML::SAX::Base

SAX, cont.

• handler-Klasse kann von XML::SAX::Base erben

package MyHandler;

use XML::SAX::Base;

@ISA = (’XML::SAX::Base’);

sub start_element {

my ($self, $data) = @_;

my $element = $data->{Name};

my $attref = $data->{Attributes};

...

}

• vorgefertigte Module, z.B. XML::Handler::XMLWriter

SAX, cont.

• Verwaltung von SAX-Parsern durch XML::SAX

• XML::SAX::parsers liefert Liste von installierten Modulen

• Auswahl eines Parsers:

my $handler = MyHandler->new;

my $factory = XML::SAX::ParserFactory->new;

my $sax = $factory->parser(Handler => $handler);

$sax->parse_uri($file);

• Anforderungen an Parser: $factory->require_feature(...)

• fallback: XML::SAX::PurePerl

DOM – Document Object Model

• Repräsentation des XML-Dokuments als Baum

• Knoten des Baums: Elemente, Attribute, Text, . . .

• Funktionen zur Navigation im Baum:

– getNodeType, getNodeName

– getParentNode, getChildNodes, getFirstChild,

getNextSibling, getAttributes,

getElementsByTagName

– appendChild, removeChild

– getTagName, {get,set}AttributeNode

• höherer Speicherverbrauch

das Beispiel als Baum

library

��������

HHHHHHHH

book

��������

���

@@@

PPPPPPPP

ATTRIBUTE title

TEXT

author

TEXT

author

TEXT

book

��� HHH

ATTRIBUTE ...

XML::DOM

• verwendet XML::Parser

• Knoten: XML::DOM::Node

• Unterklassen: XML::DOM::Element, XML::DOM::Text

• weitere Klassen: XML::DOM::Comment, XML::DOM::Entity,

XML::DOM::NodeList, . . .

XML::DOM, cont.

use XML::DOM;

my $parser = XML::DOM::Parser->new;

my $root = $parser->parsefile(’intro.xml’);

walktree($root);

print $root->toString;

sub walktree {

my ($node) = @_;

$node->setTagName(’strong’)

if $node->getNodeName eq ’blink’;

walktree($_) foreach $node->getChildNodes;

}

XML::DOM, cont.

• Zugriff auf einzelne Elemente kompliziert:

foreach $book ($root->getElementsByTagName(’book’)) {

my $title = $book->getElementsByTagName(’title’)

->item(0)->getFirstChild->getData;

my $attrs = $book->getAttributes;

my $year = $attrs->getNamedItem(’year’)->getValue;

my $ed = $attrs->getNamedItem(’edition’)->getValue

if $attrs->getNamedItem(’edition’);

...

}

• mixed content schwierig

XPath

• Anfrage-Sprache

• beschreibt Pfade im XML-Dokument

• andere Baumstruktur als DOM

• Syntax an (Unix-)Dateisystem angelehnt

• einfacher Zugriff auf Inhalte von Elementen und Attribute

• Achsen: child, parent, sibling, attribute, . . .

• Bedingungen

XPath, cont.

• Beispiele:

author alle author-Kinder des aktuellen Knotens

book/title title-Element unterhalb von book

/library library-Element unterhalb der Wurzel

//title alle title-Elemente im Dokument

book/@year year-Attribut

//book[@year=’2000’] alle Bücher aus dem Jahr 2000

//author[position()=1] erste author-Elemente

//book[@year=’2000’]/title Titel aller Bücher aus 2000

XML::XPath

use XML::XPath;

my $root = XML::XPath->new(filename => ’library.xml’);

my $books = $root->find(’/library/book[@year=2000]’);

foreach $book ($books->get_nodelist) {

my $title = $book->findvalue(’title’);

my $authors = $book->find(’author’);

my $author = join(", ",

map {$_->findvalue(’.’)} $authors->get_nodelist);

my $year = $book->findvalue(’@year’);

my $edition = $book->findvalue(’@edition’);

...

}

XML mit Perl erzeugen

• erneut: print, here-documents

• Schwierigkeit: keine vorgegebenen Tags, Attribute, Entitäten

• zwei Module: XML::Writer, XML::Generator

• bisher kein Äquivalent zu HTML::Element->new_from_lol

• Serialisierung von Datenstrukturen

XML::Writer

use XML::Writer;

my $writer = XML::Writer->new(

DATA_MODE => 1, DATA_INDENT => 2);

$writer->xmlDecl;

$writer->startTag(’library’);

$writer->startTag(’book’, year => 2000, edition => "3");

$writer->dataElement(’title’, "Programming Perl");

$writer->dataElement(’author’, "Larry Wall");

$writer->dataElement(’author’, "Tom Christiansen");

$writer->dataElement(’author’, "Jon Orwant");

$writer->endTag(’book’);

$writer->endTag(’library’);

$writer->end;

XML::Generator

use XML::Generator;

my $xml = XML::Generator->new(

pretty => 2, conformance => ’strict’);

print $xml->library(

$xml->book({edition => ’3’, year => 2000},

$xml->title(’Programming Perl’),

$xml->author(’Larry Wall’),

$xml->author(’Tom Christiansen’),

$xml->author(’Jon Orwant’)),

$xml->book({year => 1998},

$xml->title(’Advanced Perl Programming’),

$xml->author(’Sriram Srinivasan’)));

XML::Dumper

use XML::Dumper;

%bands = (beatles => {

members => [’John’, ’Paul’,

’George’, ’Ringo’],

albums => [’Help’, ’Revolver’]},

thewho => {

members => [’Roger’, ’Pete’,

’John’, ’Keith’],

albums => [’Quadrophenia’] });

my $dumper = XML::Dumper->new;

print $dumper->pl2xml(\%bands);

XML::Dumper, cont.

<perldata>

<hash>

<item key="beatles">

<hash>

<item key="albums">

<array>

<item key="0">Help</item>

<item key="1">Revolver</item>

</array>

</item>

<item key="members">

<array>

<item key="0">John</item>

<item key="1">Paul</item>

<item key="2">George</item>

<item key="3">Ringo</item>

</array>

</item>

</hash>

</item>

...

</perldata>