Klávesové zkratky na tomto webu - rozšířené Na obsah stránky

Translate to English… Ins Deutsche übersetzen…

PHP & DOM; interní poznámky

Pár postřehů k DOM API v PHP 5. Jde o funkce pro parsování, generování a manipulaci s XML a HTML soubory. Chování se může v různých verzích lišit.

$dom = new DOMDocument();

// konfigurace pro načtení
$dom->preserveWhiteSpace = FALSE;
$dom->load('input.xml');

// konfigurace pro uložení
$dom->formatOutput = TRUE;
$dom->encoding = 'utf-8';
$dom->save('output.xml');

Načtení XML souboru

  • metody $dom->load($fileName), $dom->loadXML($string)
  • konfigurační vlastnosti:
    • $dom->resolveExternals – načíst externí entity z DTD deklarace? Výchozí: FALSE
    • $dom->strictErrorChecking – throws DOMException on errors? Výchozí: TRUE
    • $dom->validateOnParse – načíst a validovat oproti DTD? Vychozí: FALSE
    • $dom->preserveWhiteSpace – zachovat redundantní white space? Výchozí: TRUE
    • $dom->substituteEntities – zaměnit jmenné entity? Výchozí: FALSE
  • validování nebo resolveExternals stahuje DTD – extrémně pomalé!
  • aby se nestahovalo DTD:
    • ponechat nastavené resolveExternals = validateOnParse = FALSE
    • nebo použít XML Catalogs (nepovedlo se mi rozchodit)
    • nebo modifikovat URL v <!DOCTYPE> na lokální kopii DTD
  • zpracování DTD je pomalé (tj. i bez stahování)
    • načtení XHTML dokumentu trvá cca 50× déle
    • validování už pak zpomalí jen mírně
  • bez zpracování DTD:
  • $dom->encoding určuje XML deklarace

Uložení XML souboru

  • metody $dom->save($fileName), $s = $dom->saveXML()
  • generují identický výstup (narozdíl od ukládání HTML)
  • konfigurační vlastnosti:
    • $dom->formatOutput – generuje „hezčí“ výstup (formátuje podivně)
    • $dom->encoding – kódování (např. utf-8, windows-1250)
    • $dom->standalone, $dom->version – XML deklarace
  • formatOutput lze povolit jen tehdy, pokud bylo načítáno s preserveWhiteSpace == FALSE
  • saveXML($node) s parametrem ignoruje encoding, vždy používá UTF-8

Načtení HTML souboru

  • metody $dom->loadHTMLFile($fileName), $dom->loadHTML($string)
  • chápe všechny HTML entity
  • ignoruje nastavení:
    • $dom->resolveExternals (vždy TRUE)
    • $dom->validateOnParse (vždy FALSE)
    • $dom->preserveWhiteSpace (vždy TRUE)
    • $dom->substituteEntities (vždy TRUE)
  • je nutné specifikovat kódování meta hlavičkou, jinak použje ISO-8859-1, ale vlastnost $dom->encoding nastaví na NULL a už nepůjde změnit při ukládání
  • přepisuje \r na &#13; → odstranit funkcí str_replace
  • funguje getElementById()
  • nevytváří plnohodnotný DOM, nedoplní např. element body (má volitelné značky)

Uložení HTML souboru

  • metody $dom->saveHTMLFile($fileName), $s = $dom->saveHTML()
  • negenerují stejný výstup!
  • pokud byl vstup načten jako XML (load, loadXML), ukládá špatně prázdné elementy
  • ignoruje nastavení:
    • $dom->formatOutput (vždy FALSE)
    • $dom->encoding
      • saveHTML použije vstupní kódování
      • saveHTMLFile použije 7bit ASCII, v meta hlavičce uvádí UTF-8 (není chyba),

Zpracování HTML souboru

// odstraníme \r
$s = file_get_contents('input.html');
$s = str_replace("\r", '', $s);

// parsujeme
$dom = new DOMDocument();
$ok = $dom->loadHTML($s);

// zjistíme obsah <title>
$title = $dom->getElementsByTagName('title')->item(0)->nodeValue;

// nebo šikovněji přes XPath:
$xpath = new DOMXPath($dom);
$title = $xpath->query('//title')->item(0)->nodeValue;

XPath: tutorial, XPather extension

Komentáře RSS 2.0 komentářů » přidat

avatar

#1 David Grudl http://davidgrudl.com nový

Tohle není článek, jen souhrn mých rešerší, sepsaný pro vlastní potřebu. Text nadále doplňuji a upravuji. Budu rád, pokud téma doplníte o další postřehy.

Posláno 27. 9. 2007 v 9.28 | Odpovědět

#2 pixy http://pixy.cz nový

Prefix: mám s tímhle nulové zkušenosti; drobný nápad: nepomohlo by přeuložit nepoužívanější DTD na lokál a přesměrovat PHP na ně?

Posláno 27. 9. 2007 v 10.37 | Odpovědět
Na komentář reagoval [3] David Grudl
avatar

#3 David Grudl http://davidgrudl.com nový

#2 pixy: asi nejsnáze to lze udělat změnou URL v <!DOCTYPE>na lokální soubor, zprovoznit XML Catalogs se mi nepodařilo. Nicméně stále je zpracování DTD velmi pomalé – asi 50× prodlouží načtení XHTML souboru.

Mnohem rychlejší je preprocesing vstupního souboru
nahradit atribut id za xml:id
nahradit jmenné entity za číselné

a pak parsovat bez DTD.

Posláno 27. 9. 2007 v 11.13 | Odpovědět
avatar

#4 marek http://www.bikenews.cz nový

nevadí že napíšu komentář k nečlánku? :) Co vedlo k napsání komentáře o nečlánku po osmi hodinách od napsání?

Posláno 27. 9. 2007 v 18.05 | Odpovědět
Na komentář reagoval [5] David Grudl
avatar

#5 David Grudl http://davidgrudl.com nový

#4 marek: to je pozůstatek jednoho smazaného komentáře a smazaných reakcí na to, že jsem jej smazal ;-)

Posláno 27. 9. 2007 ve 22.54 | Odpovědět
avatar

#6 xom http://pinion.xom-tom.com nový

Děkuju za souhrn, velice se to hodí, zvláště, když přemýšlím nad tvorbou PHP OpenXML docx generátoru, který jsem po netu hledal a nějak nenašel – pokud byste někdo o tom generátoru věděl, tak napište, ať nedělám zbytečnou práci (pro tabulkový Excel již existuje PHP Excel

Posláno 28. 9. 2007 v 10.26 | Odpovědět

Tento článek byl uzavřen. Už není možné k němu přidávat komentáře ani hlasovat

Výtah na začátek článku na první komentář

Názory čtenářů v diskusích nejsou názory provozovatele webu, a ten za jejich obsah neodpovídá.

phpFashion © 2004, 2010 David Grudlo webu

Pokud není uvedeno jinak, podléhá obsah těchto stránek licenci Creative Commons BY-NC-ND Creative Commons License BY-NC-ND

Ukázky zdrojových kódů smíte používat s uvedením autora a URL tohoto webu bez dalších omezení.