XML::LibXMLとかCPANとか
コードを書きつつも、もしかしてCPANに使い勝手がいいモジュールあがってるかもしれない、と漁る日々。
XML::LibXMLでDOM使って書けることが分かったので、延々弄ってた。
use XML::LibXML;
でいける。
iキー。
#!/usr/bin/perl use strict; use warnings; use XML::LibXML; my $doctype = 'html'; my $system = '-//W3C//DTD XHTML 1.0 Strict//EN'; my $dtd = 'http://www.w3.org/TR/xhtml/DTD/xhtml1-strict.dtd'; my $doc= XML::LibXML::Document->new('1.0','UTF-8'); $doc->createInternalSubset($doctype, $system, $dtd); my $html = $doc->createElement('html'); my $h1 = $doc->createElement('h1'); my $p = $doc->createElement('p'); $p->appendText('sample'); $h1->appendText('Hello, World!'); $doc->importNode($h1); $doc->importNode($p); $html->appendChild($h1); $html->appendChild($p); $doc->setDocumentElement($html); print $doc->toStringHTML();
escで抜ける。
:save domsample.pl
:quit
chmod 705 domsample.pl
気をつけるべき点は、createElementした直後の要素は$docのなかに収まっておらず、
$doc->importNode();
した後でappendが可能になる。ほかの言語だとそのままappendできたりするからちょっと気をつけないといけない。
my $p = $doc->createElement('p'); my $p1 = $doc->createElement('p');
と
my $p = $doc->createElement('p'); my $p1 = $p;
の違いは、前者はそれぞれが独立した要素で、後者は$p1が$pの中身を参照してる状態。後者の状態で$pに変更を行うと$p1も同じ状態になる。
$doc->importNode($p); $doc->importNode($p);
は同じ要素が複製されるわけではない。
表記上複製したりコピーしたりしているように見えるかもしれないけど、メモリ上での扱いが実際どんな形になっているかを把握しておくべき。$docにsetDocumentElementせずに、toString()してprintするとわかりやすいかもしれない。
my $p = $doc->createElement('p')->appendText('hello');
は不可能。このappendText時には未定義状態だから。