Przykład wykorzystania PHP do prezentacji danych XML

W jednym z poprzednich wpisów pokazałem ciekawe zastosowanie klasy DOMDocument umożliwiające wygodne przeglądanie zawartości kodu HTML. Tym razem chciałbym pokazać inne, równie interesujące jej wykorzystanie.

Funkcja var_dump w języku PHP jest niewątpliwie najbardziej typową metodą wykorzystywaną do podglądu zawartości zarówno zmiennych jak i obiektów. Niestety nie zawsze ten sposób prezentacji danych jest wygodny w użyciu czego doskonałym przykładem może być prezentowanie kodu XML. Ktoś mógłby teraz zapytać czy dane XML są aż tak popularne w języku PHP, że warto się nimi w ogóle przejmować? Otwórz okazuje się, że tak – szczególnie jeśli ktoś próbował bawić się w usługi SOAP, gdzie zarówno zapytania jak i odpowiedzi są niczym innym jak właśnie kodem XML (i to często o dosyć rozbudowanej strukturze).

W przypadku prezentacji kodu XML problem polega na tym, iż ten najczęściej pozbawiony jest jakiegokolwiek formatowania. Dlatego też często zamiast widzieć np. coś takiego (prezentowany kod XML jest wymyślony i jego zbieżność z czymkolwiek rzeczywistym jest co najwyżej przypadkowa 🙂 )

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope/" soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
	<soap:Body>
		<GetKsiazkaResponse>
			<Ksiazka>
				<Autor>Isaac Asimov</m:Autor>
				<Tytul>Nemezis</Tytul>
			</Ksiazka>
		</GetKsiazkaResponse>
	</soap:Body>
</soap:Envelope> 

możemy zobaczyć to

<?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope/" soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding"><soap:Body><GetKsiazkaResponse><Ksiazka><Autor>Isaac Asimov</m:Autor><Tytul>Nemezis</Tytul></Ksiazka></GetKsiazkaResponse></soap:Body></soap:Envelope> 

Czy możemy coś z tym zrobić? Okazuje się, że tak. Naszą „zabawę” rozpoczniemy jednak od poświęcenia chwili czasu zagadnieniu samego wyświetlania kodu XML w przeglądarce. Moglibyśmy co prawda posłużyć się zwykłą funkcją var_dump ale w efekcie przeglądarka potraktuje znaczniki XML podobnie jak kod HTML (w końcu HTML to też taki XML, o czym pisałem już tutaj) i naszym oczom ukazałoby się coś takiego

string(316) "Isaac AsimovNemezis" 

Osobiście do wyświetlania tego typu treści bardzo chętnie wykorzystywałem niezwykle wygodny tag HTML <xmp>. Obecnie jest on już niestety uznany za przestarzały i został wycofany w HTML5. Przeglądarki potrafią sobie co prawda jeszcze z tym tagiem poradzić ale my pójdziemy za sugestią dokumentacji i wykorzystamy znaczniki <code> oraz <pre>. Dodatkowo musimy też zadbać o zastąpienie znaków < oraz > ich odpowiednikami < oraz > (za to również lubiłem znacznik <xmp> – w jego przypadku nie trzeba było tego robić 😉 ). Nasz kod do wyświetlania będzie mógł wyglądać np. tak

echo '<pre><code>'.htmlentities($xml).'</code></pre>';

Szybkie sprawdzenie działania tego kodu pokaże nam taki rezultat

<?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope/" soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding"><soap:Body><GetKsiazkaResponse><Ksiazka><Autor>Isaac Asimov</Autor><Tytul>Nemezis</Tytul></Ksiazka></GetKsiazkaResponse></soap:Body></soap:Envelope>

Powyższy XML niby nie jest jakoś specjalnie skomplikowany ale jak dla mnie czytanie takiego potoku znaków wygodne po prostu nie jest. Spróbujmy zatem trochę ułatwić sobie życie i jakoś ten kod sformatować. Sposobów na to jest zapewne wiele (można np. spróbować iterować po strukturze i rozpoznawać zagnieżdżenia) ale ja chciałbym zaproponować wykorzystanie wspomnianej na początku klasy DOMDocument. Przejdźmy od razu do kodu.

//Tworzymy obiekt naszej klasy
$dom = new \DOMDocument();

//Ładujemy nasz kod XML
$dom->loadXML($xml);

//Zezwalamy na usuwanie nadmiarowych białych znaków z naszego XML
$dom->preserveWhiteSpace = false;

//Gwódź programu - włączamy formatowanie kodu wynikowego
$dom->formatOutput = true;

//Zapisujemy wynik do zmiennej
$przyjaznyXML = $dom->saveXML();

//Wyświetlamy wynik
echo "<pre><code>".htmlentities($przyjaznyXML)."</code></pre>";

Jak widać najważniejszym elementem, którego zadaniem jest ułatwienie nam życia to właściwość formatOutput rzeczonej klasy DOMDocument. Zobaczmy jeszcze jak wygląda nasz XML po potraktowaniu go powyższym kodem

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope/" soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
  <soap:Body>
    <GetKsiazkaResponse>
      <Ksiazka>
        <Autor>Isaac Asimov</Autor>
        <Tytul>Nemezis</Tytul>
      </Ksiazka>
    </GetKsiazkaResponse>
  </soap:Body>
</soap:Envelope>

Prawda, że tak sformatowany wynik czyta się wygodniej? Jak widać niepozorna, wydawałoby się, klasa służąca do parsowania kodu XML może mieć wiele interesujących zastosowań. Czy to jednak wszystko na co ją stać? Wg mnie nie, ale to postaram się pokazać w innych wpisach w przyszłości.

Na zakończenie podam jeszcze kompletny kod gdyby ktoś chciał się samemu „pobawić” 🙂

<?php
//Przygotowujemy treść kodu XML
$xml = '<?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope/" soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding"><soap:Body><GetKsiazkaResponse><Ksiazka><Autor>Isaac Asimov</Autor><Tytul>Nemezis</Tytul></Ksiazka></GetKsiazkaResponse></soap:Body></soap:Envelope>';

//Formatujemy kod XML przy pomocy klasy DOMDocument
$dom = new \DOMDocument();
$dom->loadXML($xml);
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$przyjaznyXML = $dom->saveXML();

//Wyświetlamy "pierwotny" kod XML
echo "<pre><code>".htmlentities($xml)."</code></pre>";

//Wyświetlamy sformatowany kod XML
echo "<pre><code>".htmlentities($przyjaznyXML)."</code></pre>";

Mogą zainteresować Ciebie również poniższe wpisy

Comments are closed.