einführung in perl - techfak.uni-bielefeld.de · xml Œ extensible markup language ist ... Œ...
TRANSCRIPT
Ü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: & < > ' "
• 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>