XSLT + XML = HTML

Oke, gw mau sekedar bagi-bagi ilmu, kali ini untuk membuat halaman HTML yang ‘dinamis’. Pertama-tama, HTML yang dinamis yang gw maksudkan disini adalah HTML yang digunakan untuk menampilkan data, bukan ‘dinamis’ dalam arti server-side scripting.

Misalnya karena alasan tertentu, program harus bisa mengeluarkan output dalam bentuk HTML, entah laporan untuk ditampilkan secara online, atau karena program menggunakan embedded browser seperti Mozilla Active-X, atau WebBrowser (yang sudah ada di Delphi) sebagai user interface.

Apa itu XSLT, XML?

Nama XSLT dan XML mungkin sudah pernah anda dengar (kalau belum, yaa.. gak papa juga sih). Secara garis besar, XML hanya container data –yang lebih mudah untuk dibaca oleh manusia– yang artinya XML tidak berurusan dengan presentasi data tersebut. Tapi karena kita ingin menampilkan data XML tersebut di browser, maka kita harus mengubahnya menjadi dokumen HTML.

Disinilah peran dari XSLT, yaitu mengubah XML tersebut jadi bentuk (umumnya dalam format XML juga) lainnya. File XSL berisi ‘template’ HTML dokumen akhir, dan juga cara untuk menyusun HTML tersebut tergantung dari data yang diberikan oleh XML.

Jadi versi singkatnya:
– XML adalah data yang ingin ditampilkan
– XSLT merubah XML jadi dokumen (XML) lainnya.

Apa yang dibutuhkan

Sebelum menggunakan XML dan XSLT lebih baik anda membaca-baca dulu informasi mengenai kedua X ini. XML, XSLT, DTD dan sebagainya dapat anda pelajari secara gratis di W3Schools.

Untuk menggunakan XML di Delphi sebenarnya ada beberapa pilihan. Menggunakan komponen open source seperti OpenXML, libxml2-pas atau menggunakan library XML dari Microsoft (MSXML.dll) yang sudah ada semenjak Internet Explorer 5 (walaupun implementasinya baru bener-bener ‘bener’ di IE 6).

NOTE: MSXML.dll adalah Active-X DLL, jadi kalau ingin anda gunakan harus di register dulu sebagai Active-X component di Delphi.

Dari ketiganya gw menggunakan libxml2-pas, perlu diketahui bahwa libxml2-pas ini (tidak seperti ‘aslinya’, libxml2. Ini karena Delphi tidak bisa menggunakan file OBJ dari compiler lain) membutuhkan beberapa file eksternal seperti iconv.dll, libxml2.dll, libxslt.dll, libexslt.dll, dan zlib1.dll yang semuanya dapat di download disini .

Karena libxml2 dibuat menggunakan C maka libxml2-pas pun mewarisi sifat libxml2. Ini artinya libxml2-pas gak (atau mungkin belum?) memiliki class-class seperti yang ada di OpenXML (walaupun kayaknya akan lebih bagus kalau ada yang bikin class wrapper untuk libxml2-pas), sebaliknya ada banyak sekali function (sangat library-ish.. :D) yang bisa digunakan. Tapi tentu saja, kita gak harus mengetahui semua fungsi yang ada. Dalam kasus ini kita hanya perlu mengenal beberapa function saja.

Menggunakan libxml2-pas

Untuk lebih memudahkan penjelasan, gw akan memberikan contoh data XML sebagai berikut:

<?xml version="1.0" encoding="UTF-8"?><toko id="389">

  <nama>Toko Pasti Rugi</nama>

  <alamat>

    <kota id="3">Jakarta</kota>

    <telepon>021 9876543</telepon>

  </alamat>

  <contactperson sex="male">

    <nama>Jono Sumarjono</nama>

    <email>jono@tokopastirugi.com</email>

  </contactperson>

</toko>

Dari XML tersebut, ada data mengenai Toko Pasti rugi, dengan contact-person Jono Sumarjono. Misalkan, program ingin membuat HTML yang menampilkan data toko tersebut. Ini adalah contoh XLST yang digunakan untuk menampilkan data tersebut :

<?xml version='1.0'?>

<xsl:stylesheet version="1.0"

    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="html"/>

  <xsl:template match="/toko">

    <html>

      <head>

        <title>Data Toko: <xsl:value-of select="nama" /></title>

      </head>

      <body>

        <h1><xsl:value-of select="nama" /></h1>

        <h4><xsl:value-of select="@id" /></h4>

        <hr />

<p>Contact Person :

        <xsl:choose>

          <xsl:when test="contactperson/@sex = 'male'">Bapak </xsl:when>

          <xsl:when test="contactperson/@sex != 'male'">Ibu </xsl:when>

        </xsl:choose>

        <xsl:value-of select="contactperson/nama" /></p>

        <p><a href="mailto:{contactperson/email}">Kirim e-mail</a></p>

        <hr />

<p>Kota : <xsl:value-of select="alamat/kota" />

 	   (<xsl:value-of select="alamat/kota/@id" />)</p>

        <p>Nomor telepon : <xsl:value-of select="alamat/telepon" /></p>

      </body>

    </html>

  </xsl:template>

</xsl:stylesheet>

Jangan takut kalau anda tidak mengerti apa arti dokumen ini (mungkin ini saatnya situ mulai belajar XSLT). Sebaliknya kalau anda sudah mengetahui/akrab dengan XSL ini hanya contoh sederhana saja (tau deh yang bisa bikin lebih canggih :D).

Untuk membuat dokumen XSL sederhana ini cukup mudah, pertama-tama buat dokumen HTML (atau lebih tepatnya XHTML) lalu tinggal tambahkan bagian

  <?xml version='1.0'?>

  <xsl:stylesheet version="1.0"

       xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  <xsl:output method="html"/>

    <xsl:template match="/namarootelement">

di awal file, dan

    </xsl:template>

  </xsl:stylesheet>

pada bagian akhir file. Setelah itu, untuk bagian-bagian yang ingin diisi data dari XML gunakan

  <xsl:value-of select="/elementpath/namaelement" />

untuk mengakses value element, dan

  <xsl:value-of select="/elementpath/namaelement/@namaattribute" />

untuk mengakses value attribute element tersebut. Untuk menggunakan value dari XML pada tempat diantara tanda petik, gunakan

  <a href="{/elementpath/namaelement}">Some link</a>

Membuat dokumen XML

Pertama-tama, mungkin yang ingin anda tahu adalah bagaimana merubah data yang ada ke dalam bentuk XML. Gw dah membuat sebuah contoh program untuk membuat dokumen XML kasus ini, silahkan download disini. Ini adalah sebagian dari code dari program itu :

  xmlDoc := xmlNewDoc('1.0');

  try

    rootNode := xmlNewNode(nil, PChar('toko'));    xmlDocSetRootElement(xmlDoc, rootNode);

    //  toko 'id' attribute

    xmlNewProp(rootNode, PChar(SID), PChar(IntToStr(AData.ID)));

...

Code itu menunjukkan konstruksi dokumen XML baru, dengan root element bernama ‘toko’ dan selanjutnya menulis attribute ‘id’ ke element tersebut.

Function xmlNewNode digunakan untuk membuat element baru dengan return-value pointer ke element yang baru dibuat. Pointer ini dapat digunakan oleh function lainnya seperti xmlNewProp untuk menambahkan attribute ke element tersebut.

Function xmlDocSetRootElement bertujuan untuk menentukan root dari dokumen XML tersebut, karena XML harus memiliki satu root maka element ‘toko’ digunakan sebagai root.

Menggunakan libxslt

Setelah data XML sudah ada dan template XSLT sudah ada, maka langkah selanjutnya adalah menggabungkan keduanya. Pertama-tama yang dilakukan adalah me-load template yang digunakan, ada beberapa cara untuk melakukan hal itu. Pertama, dengan menggunakan function xsltParseStylesheetFile untuk meload file template HTML tersebut.

  ...  xslStyle := nil;

  xslStyle := xsltParseStylesheetFile(PChar(ExtractFilePath(ParamStr(0)) + 'filexsl.xsl'));

if not Assigned(xslStyle) then

    raise Exception.Create('Document XSL tidak bisa di load');

...

Tentu saja, ini hanya berlaku apabila template yang digunakan berupa file, tapi bagaimana kalau template tersebut disimpan sebagai resource dalam file EXE program, atau DLL? Anda bisa gunakan function berikut

  function StringToXMLDocPtr(const AString: string): Pointer;

  var

    cTxt: xmlParserCtxtPtr;

  begin

    Result := nil;    xmlInitParser();

    cTxt := xmlCreateMemoryParserCtxt(PChar(AString), Length(AString));

if not Assigned(cTxt) then

      Exit;

xmlParseDocument(cTxt);

    if (cTxt.wellFormed <> 0) then

      Result := cTxt.myDoc

    else

      begin

        xmlFreeDoc(cTxt.myDoc);

        cTxt.myDoc := nil;

      end;

xmlFreeParserCtxt(cTxt);

  end;

...

//  cara menggunakan StringToXMLDocPtr

    xslDoc := StringToXMLDocPtr(sTemplateInAString);

untuk mengubah string (dan juga memeriksanya apakah berisi XML yang valid) menjadi pointer yang bisa digunakan oleh function xsltParseStylesheetDoc. Gw juga dah membuat sebuah contoh program untuk membaca template XSL dari resource, silahkan download disini.

Sekarang yang tersisa adalah bagaimana menggabungkan XML, dan XSL (dari file atau dari string) untuk menghasilkan HTML. Function xsltParseStylesheetFile dan xsltParseStylesheetDoc ini memiliki return value berupa pointer (tepatnya xsltStylesheetPtr) yang bisa digunakan oleh function lainnya bernama xsltApplyStylesheet yang bertujuan untuk menggunakan template XSL terhadap data XML.

Function xsltApplyStylesheet memiliki tiga parameter, yang pertama adalah pointer dengan tipe xsltStylesheetPtr yang sudah disebutkan sebelumnya, yang kedua adalah pointer dengan tipe xmlDocPtr yaitu dokumen XML yang ingin digunakan, dan yang ketiga untuk parameter yang bisa tidak kita gunakan dengan memberikan value nil.

Berikut adalah contoh code menggabungkan dokumen XML dengan XSL untuk menghasilkan dokumen baru, yang ditunjukkan dengan variabel resultDoc.

var

  xmlDoc, resultDoc: xmlDocPtr;

  aNode: xmlNodePtr;

  xslStyle: xsltStylesheetPtr;  ...

xmlDoc := xmlNewDoc('1.0');

  aNode := xmlNewNode(nil, PChar('somedata'));

  xmlDocSetRootElement(xmlDoc, aNode);

  xmlNewNode(aNode, PChar('someelement'), PChar('value'));

  xmlNewNode(aNode, PChar('anotherelement'), PChar('another value'));

xslStyle := xsltParseStylesheetFile(PChar(ExtractFilePath(ParamStr(0)) + 'filexsl.xsl'));

if Assigned(xslStyle) then

  begin

    resultDoc := xsltApplyStylesheet(xslStyle, xmlDoc, nil);

if not Assigned(resultDoc) then

      raise Exception.Create('Tidak bisa menghasilkan dokumen HTML');

  end;

...

Setelah sampai disini variabel resultDoc sudah berisi dokumen HTML hasil gabungan antara xmlDoc dan xslStyle. Untuk menggunakan hasilnya, kita bisa menyimpannya ke file menggunakan function xsltSaveResultToFilename

  ...  //  simpan html ke file output.html

  if (xsltSaveResultToFilename(PChar(ExtractFilePath(ParamStr(0)) + 'output.html'), resultDoc, xslStyle, 0) = -1) then

    raise Exception.Create('Tidak bisa menulis file ''output.html''');

atau menjadi string menggunakan function xsltSaveResultToString.

var

  tempP: PChar;

  iLen: Integer;

  sHTML: string;  ...

if (xsltSaveResultToString(@tempP, @iLen, resultDoc, xslStyle) = -1) then;

  raise Exception.Create('Tidak bisa mengambil output HTML ke string')

  else

  begin

    SetString(sHTML, tempP, iLen);

...

Untuk merangkum semuanya, gw sudah buat sebuah program yang membuat dokumen XML, membaca XSL dari resource, dan menggunakan XSL kepada XML, dan menyimpan hasilnya sebagai file atau dalam string, silahkan ambil disini.

Kesimpulan

Menggunakan XSLT untuk membuat presentasi data XML tidak sulit, selama anda memiliki kemampuan yang dibutuhkan. Tulisan ini hanya membahas sebagian kecil dari XSLT, XML, dan libxml2 sisanya terserah anda untuk mencari lebih dalam. Perlu diketahui bahwa XSLT dapat melakukan hal-hal seperti pencabangan (seperti yang ditunjukkan pada XSL yang digunakan dalam contoh kasus), loop, recursive stylesheet, dst.. gw sengaja tidak menunjukkan hal itu disini karena itu tugas anda. Saya harap tulisan ini cukup menggugah rasa penasaran dan keinginan untuk bereksperimen anda.

Penggunaan (X)HTML, XSLT, dan XML memungkinkan program menggunakan web-browser sebagai interfacenya. Hal ini sangat menguntungkan karena ditangan yang tepat kemampuan browser untuk menghasilkan halaman-halaman web yang menarik dapat menghasilkan interface program yang unik. Untuk itu mar… capek ah, mikir sendirilah kesimpulannya.

Oh ya, dokumentasi libxml2 juga sangat lengkap, dan bisa di download.

Advertisements

2 Comments

Filed under Ilmu

2 responses to “XSLT + XML = HTML

  1. risca

    wew.. kuk nda bs di dunlud ya?

  2. Xaie

    Maaf, maklum pakai host gratisan untuk IIX.
    Sekarang seharusnya sudah bisa.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s