XSLT (Extensible Stylesheet Language Transformation) Notlarım

Neslihan Esra Altınışık
7 min readJul 28, 2020

--

XML’in core teknolojilerinden biridir. XML formatındaki dokümanı başka bir formata dönüştürmek için kullanılır. Source kaynak değişmez, yeni bir kaynak oluşturulur. XSLT stil sayfasındaki (stylesheet) kurallar, XSLT Processor’üne çıktının ne olması gerektiği söyler. Çıktı XML, HTML, metin yada başka bir formatta dosya olarak kaydedilebilir. XSLT ile dönüştürülen öğelerin konumu, source dokümandan XPath ile seçilir.

XSLT Dönüşümü
<?xml version=”1.0" encoding=”UTF-8" ?>
<xsl:stylesheet xmlns:xsl=”http://www.w3.org/1999/XSL/Transform" version=”2.0">
<!-- Bu deklarasyon, XSLT Processor’üne xml dokümanındaki hangi bölümün formatlanacağını söyler. -->
<xsl:template match=”/”>
<!-- Dönüşüm işlemi burada gerçekleşir -->
</xsl:template>
</xsl:stylesheet>

Uygulama 1: Öğrenci bilgilerinin tutulduğu dokümanı HTML formatındaki tabloya dönüştürme

<xsl:for-each select=”tanım”> : Select özelliğindeki ifadeye göre node dizisindeki her kümeye aynı işlemi uygular.

<xsl:value-of select=”tanım” disable-output-escaping=”yes”|”no” (eğer “yes” ise bu elementinin içeriğindeki özel karakterler dönüştürülmeden çıkarılır)/> : Select özelliğindeki ifadenin değerini string olarak yazar.

XML dosyası

<?xml version="1.0" encoding="UTF-8"?> 
<?xml-stylesheet type="text/xsl href="student.xsl" ?>
<student>
<s>
<name> Hale </name>
<branch> CS</branch>
<age>18</age>
<city> Ankara </city>
</s>
<s>
<name> Akif </name>
<branch> IT</branch>
<age> 25 </age>
<city> İstanbul</city>
</s>
</student>

XSL dosyası (student.xsl)

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h1 align="center">Öğrenci Bilgileri</h1>
<table align="center" >
<tr>
<th>Ad Soyad</th>
<th>Bölüm</th>
<th>Yaş</th>
<th>Şehir</th>
</tr>
<xsl:for-each select="student/s">
<tr>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="branch"/></td>
<td><xsl:value-of select="age"/></td>
<td><xsl:value-of select="city"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

Sonuç

<html>
<body>
<h1 align="center">Öğrenci Bilgileri</h1>
<table align="center">
<tr>
<th>Ad Soyad</th>
<th>Bölüm</th>
<th>Yaş</th>
<th>Şehir</th>
</tr>
<tr>
<td> Hale </td>
<td> CS </td>
<td> 18 </td>
<td> Ankara </td>
</tr>
<tr>
<td> Akif </td>
<td> IT </td>
<td> 25 </td>
<td> İstanbul </td>
</tr>
</table>
</body>
</html>

Uygulama 2: Sıralama

<xsl:sort select=”sıralanacak_xml_elementinin_adi” order=”ascending”|”descending” case-order=”upper-first”|”lower-first” lang=”tr(bu değer latin alfabesine göre sıralar)” data-type=”text”|”number”|”QName(kullanıcı tanımlı veri tipi demek)”/> : Bu element <xsl:apply-templates> ya da <xsl:for-each> elementlerinin içinde kullanılır. Verilen attribute’lerin kullanımı zorunlu değildir.

<xsl:apply-templates select="tanım"(XSLT processor’ün hangi node’ları işleyeceği seçilir)> : Her zaman <xsl:template> elementinin içinde yer alır. XSLT processor tarafından select özelliğiyle seçilen node kümesindeki her bir node’a tema uygulanmasını sağlar.

<xsl:output method=”xml”|”html” media-type=”MIME-type”(Karşı tarafın anlaması için çıktının veri türü belirtilebilir) version=”ciktinin-versiyonu-yazilir” omit-xml-declaration=”yes”|”no”(“no” değeri atanmış ise çıkan dokümanın sonunda XML bildirimi oluşur) indent=”yes”|”no”(Çıktıdaki hiyerarşik yapının girintisi olup omayacağı belirlenebilir)/> : Eğer net şekilde çıktının XML, HTML yoksa metin olacağı tanımlanır.

<xsl:text disable-output-escaping=”yes”|”no”>: Sonuca direk bir metin eklenilmek için kullanılır.

XML dosyası

<?xml version="1.0" ?>
<famous-persons>
<persons category="medicine">
<person>
<firstname> Edward </firstname>
<name> Jenner </name>
</person>
<person>
<firstname> Gertrude </firstname>
<name> Elion </name>
</person>
</persons>
<persons category="computer science">
<person>
<firstname> Charles </firstname>
<name> Babbage </name>
</person>
<person>
<firstname> Alan </firstname>
<name> Touring </name>
</person>
</persons>
<persons category="astronomy">
<person>
<firstname> Tycho </firstname>
<name> Brahe </name>
</person>
<person>
<firstname> Galileo </firstname>
<name> Galilei </name>
</person>
</persons>
</famous-persons>

XSL dosyası (famousPersons.xsl)

<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" /><!-- kişileri "category" niteliklerine göre sıralama -->
<xsl:template match="/">
<html>
<head><title>Sıralama Yapma</title></head>
<body>
<xsl:apply-templates select="famous-persons/persons">
<xsl:sort select="@category"/>
</xsl:apply-templates>
</body>
</html>
</xsl:template>

<!-- "category" niteliğindeki kişileri sırasıyla "name" ve "firstname" bilgilerine göre sıralama -->
<xsl:template match="persons">
<h2> <xsl:value-of select="@category"/></h2>
<ul>
<xsl:apply-templates select="person">
<xsl:sort select="name"/>
<xsl:sort select="firstname"/>
</xsl:apply-templates>
</ul>
</xsl:template>

<!-- kişi bilgilerin formatlanması -->
<xsl:template match="person">
<xsl:text disable-output-escaping="yes">
&lt;li&gt;
</xsl:text>
<b> <xsl:value-of select="name"/> </b>
<xsl:value-of select="firstname"/>
<xsl:text disable-output-escaping="yes">
&lt;/li&gt;
</xsl:text>
</xsl:template>
</xsl:stylesheet>

Sonuç : (Tarayıcı daki görünümü)

Uygulama 3: Koşul belirtme ve koşula göre içerik oluşturma

<xsl:if test="test-kosulu">

<! — Test özelliği true dönerse, bu kısım da işlemler gerçekleşir — >

</xsl:if>

Birçok seçenek arasından seçim yapmak için “xsl:choose” elementi kullanılır.

<xsl:choose>

<xsl:when test=”kosul-1”>

<! — Test özelliği true dönerse, bu kısım da işlemler gerçekleşir -->

</xsl:when>

<xsl:when test=”kosul-2”></xsl:when>

<xsl:otherwise>

<! — Eğer koşullara uyan durum yoksa bu kısımdaki işler gerçekleşir — >

</xsl:otherwise>

</xsl:choose>

<xsl:message terminate="yes" |”no” (“no” değeri atanmış ise hatayla karşılaşılsa bile dönüştürme işlemi devam eder)> : Genel olarak verilen koşul sağlanmadığında, XSLT processor tarafından hata mesajı vermek için kullanılır.

XML dosyası

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="catalog.xsl"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company></company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
<cd>
<title>Greatest Hits</title>
<artist>Dolly Parton</artist>
<country>USA</country>
<company>RCA</company>
<price>9.90</price>
<year>1982</year>
</cd>
<cd>
<title>Black angel</title>
<artist>Savage Rose</artist>
<country>EU</country>
<company>Mega</company>
<price>10.90</price>
<year>1995</year>
</cd>
<cd>
<title>1999 Grammy Nominees</title>
<artist>Many</artist>
<country>USA</country>
<company>Grammy</company>
<price>10.20</price>
<year>1999</year>
</cd>
<cd>
<title>Big Willie style</title>
<artist>Will Smith</artist>
<country>USA</country>
<company>Columbia</company>
<price>9.90</price>
<year>1997</year>
</cd>
<cd>
<title>Soulsville</title>
<artist>Jorn Hoel</artist>
<country>Norway</country>
<company>WEA</company>
<price>7.90</price>
<year>1996</year>
</cd>
<cd>
<title>The dock of the bay</title>
<artist>Otis Redding</artist>
<country>USA</country>
<company>Stax Records</company>
<price>7.90</price>
<year>1968</year>
</cd>
</catalog>

XSL dosyası

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="/">
<html>
<head></head>
<body>
<h2>My CD Collection</h2>
<table border="2">
<tr align="center" bgcolor="green">
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<xsl:sort select="artist" lang="tr" order="descending"/>
<xsl:if test="company=''">
<xsl:message terminate="no">
A company field is empty
</xsl:message>
</xsl:if>
<xsl:if test="country='USA'">
<tr>
<td> <xsl:value-of select="title"/> </td>
<xsl:choose>
<xsl:when test="price &gt; 10">
<td bgcolor="pink"> <xsl:value-of select="artist"/> </td>
</xsl:when>
<xsl:when test="price > 9">
<td bgcolor="gray"> <xsl:value-of select="artist"/> </td>
</xsl:when>
<xsl:otherwise>
<td> <xsl:value-of select="artist"/> </td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:if>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

Sonuç:

Uygulama 4: Yeni element oluşturma ve seçme

<xsl:element name=”element-adi”> : Çıkan dokümanda yeni element oluşturur.

<xsl:element name="örnek:element-adi" namespace="http://www.onek.com/foo"> : Namespace önekiyle element oluşturma yöntemi.

<xsl:attribute name=”attribute-name”> : <xsl:element> elementiyle oluşturan elemente nitelik ekler.

<xsl:transform>: <xsl:stylesheet> elementi ile aynı işi yapar.

XML Dosyası

<?xml version='1.0'?>
<SimplePurchase>
<CustomerID>9443</CustomerID>
<Date>2002-03-30</Date>
<Items>
<Item SKU="DD9981" Quantity="4" Price="3.00">Dooda</Item>
<Item SKU="WD1239" Quantity="2" Price="10.00">Widget</Item>
<Item SKU="ABC3882" Quantity="1" Price="220.00">Acme Fitsat</Item> </Items>
</SimplePurchase>

XSL Dosyası-1

<?xml version="1.0"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:element name="PurchaseSummary">
<xsl:attribute name="PurchaserID">
<xsl:value-of select="/SimplePurchase/CustomerID"/>
</xsl:attribute>
<xsl:element name="NumItemsBought">
<xsl:value-of select="count(/SimplePurchase/Items/Item)"/>
</xsl:element>
<xsl:apply-templates select="/SimplePurchase/Items/Item" />
</xsl:element>
</xsl:template>
<xsl:template match="Item">
<xsl:element name="Item">
<xsl:value-of select="."/>
</xsl:element>
<xsl:element name="SKU">
<xsl:value-of select="@SKU"/>
</xsl:element>
<xsl:element name="Quantity">
<xsl:value-of select="@Quantity"/>
</xsl:element>
<xsl:element name="Price">
<xsl:value-of select="@Price"/>
</xsl:element>
</xsl:template>
</xsl:transform>

Sonuç-1

<?xml version="1.0" encoding="UTF-8"?>
<PurchaseSummary PurchaserID="9443">
<NumItemsBought>3</NumItemsBought>
<Item>Dooda</Item>
<SKU>Dooda</SKU>
<Quantity>Dooda</Quantity>
<Price>Dooda</Price>
<Item>Widget</Item>
<SKU>Widget</SKU>
<Quantity>Widget</Quantity>
<Price>Widget</Price>
<Item>Acme Fitsat</Item>
<SKU>Acme Fitsat</SKU>
<Quantity>Acme Fitsat</Quantity>
<Price>Acme Fitsat</Price>
</PurchaseSummary>

XSL Dosyası-2 : Bu uygulamadaki örnek XML dokümanının “XMML” namespace önekiyle yeni elementler oluşturma

<?xml version="1.0"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:element name="XMML:PurchaseSummary" namespace="http://www.XMML.com/Finance">
<xsl:attribute name="PurchaserID">
<xsl:value-of select="//CustomerID"/>
</xsl:attribute>
</xsl:element>
<xsl:element name="XMML:NumItemsBought" namespace="http://www.XMML.com/Finance">
<xsl:value-of select="count(//Item)"/>
</xsl:element>
<xsl:apply-templates select="//Item"/>
</xsl:template>
<xsl:template match="Item">
<xsl:element name="XMML:Item" namespace="http://www.XMML.com/Finance">
<xsl:value-of select="."/>
<xsl:element name="XMML:SKU" namespace="http://www.XMML.com/Finance">
<xsl:value-of select="@SKU"/>
</xsl:element>
<xsl:element name="XMML:Quantity" namespace="http://www.XMML.com/Finance">
<xsl:value-of select="@Quantity"/>
</xsl:element>
<xsl:element name="Price" namespace="http://www.XMML.com/Finance">
<xsl:value-of select="@Price"/>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:transform>

Sonuç-2

<?xml version="1.0" encoding="UTF-8"?>
<XMML:PurchaseSummary xmlns:XMML="http://www.XMML.com/Finance" PurchaserID="9443"/>
<XMML:NumItemsBought xmlns:XMML="http://www.XMML.com/Finance">3</XMML:NumItemsBought>
<XMML:Item xmlns:XMML="http://www.XMML.com/Finance">Dooda<XMML:SKU>DD9981</XMML:SKU>
<XMML:Quantity>4</XMML:Quantity>
<Price xmlns="http://www.XMML.com/Finance">3.00</Price>
</XMML:Item>
<XMML:Item xmlns:XMML="http://www.XMML.com/Finance">Widget<XMML:SKU>WD1239</XMML:SKU>
<XMML:Quantity>2</XMML:Quantity>
<Price xmlns="http://www.XMML.com/Finance">10.00</Price>
</XMML:Item>
<XMML:Item xmlns:XMML="http://www.XMML.com/Finance">Acme Fitsat<XMML:SKU>ABC3882</XMML:SKU>
<XMML:Quantity>1</XMML:Quantity>
<Price xmlns="http://www.XMML.com/Finance">220.00</Price>
</XMML:Item>

Uygulama 5: Global key tanımlama

<xsl:key name=”key-adi” match=”key-in-uygulanacagi-tanim” use=”tanim” (match niteliğinde seçilen node içindeki elementin ya da attribute’ün değer seçilebilir)/> : key(parametre1, parametre2) fonksiyonuyla kullanılır. parametre1, key’in adı, parametre2 ise use niteliğinde seçilen değerin eşleşeceği kriter bilgisi girilir.

XML Dosyası

<persons>
<person name="Tarzan" id="050676"/>
<person name="Donald" id="070754"/>
<person name="Dolly" id="231256"/>
</persons>

XSL Dosyası

<?xml version="1.0" encoding="UTF-8"?>
<xsl:output method="xml" indent="yes"/>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="user" match="person" use="@id"/>
<xsl:template match="/">
<xsl:for-each select="key('user','050676')">
<xsl:element name="user">
<xsl:element name="id">
<xsl:value-of select="@id"/>
</xsl:element>
<xsl:element name="name">
<xsl:value-of select="@name"/>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Sonuç

<?xml version="1.0" encoding="UTF-8"?>
<user>
<id>050676</id>
<name>Tarzan</name>
</user>

Uygulama 6: Numara formatlama

<xsl:variable name=”referans-adi” select=”deger-atama”(Xpath tanımı yapılarak değişkene değer atalabilir)>: Global ya da local olarak değişken tanımlar. Local değişken tanımlamak için <xsl:template> elementini içinde, global olarak tanımlamak için <xsl:stylesheet>elementinin içinde olmalıdır. Tanımlı değişken kullanılırken referans verilen ismin başına $(referans-adi) yerleştirilir. Değişken değeri atandığı zaman değiştirilemez. Değişkene değer atama <xsl:variable> elementinin içine ya da select niteliğine değer vererek gerçekleştirilir.

<xsl:number count=”Xpath-tanimi-ile-node-toplami” “from”=”sayi-dizisi-baslangici” format=”ciktinin-formati” grouping-seperator=”basamak-gruplama-yapirken-kullanilacak-karakter” grouping-size=”basamak-grubundaki-karakter-sayisi”>: Hem numarayı formatlamak hem de maddeli işaretleme yapmak için kullanılır. Birçok attribute ile kullanılabilir, bu madde de sadece bir kaçı bulunmaktadır.

<xsl:number value="7" format="i:"/>
Çıktı: "vii"

XML Dosyası

<?xml version="1.0" encoding="UTF-8"?>
<book>
<chapter>
<title>Alfa Romeo</title>
<sect1>
<title>Bentley</title>
</sect1>
<sect1>
<title>Chevrolet</title>
<sect2>
<title>Dodge</title>
<sect3>
<title>Eagle</title>
</sect3>
</sect2>
</sect1>
</chapter>
<chapter>
<title>Ford</title>
<sect1>
<title>GMC</title>
<sect2>
<title>Honda</title>
<sect3>
<title>Isuzu</title>
</sect3>
</sect2>
<sect2>
<title>Mercedes</title>
</sect2>
<sect2>
<title>Nash</title>
<sect3>
<title>Opel</title>
</sect3>
<sect3>
<title>Pontiac</title>
</sect3>
</sect2>
</sect1>
<sect1>
<title>Toyota</title>
</sect1>
</chapter>
</book>

XSL Dosyası

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" />
<xsl:template match="book">
<xsl:for-each select="chapter|.//sect1|.//sect2|.//sect3">
<xsl:variable name="value1">
<xsl:number level="any" count="chapter|sect1|sect2|sect3"/>
</xsl:variable>
<xsl:number value="$value1 + 999" grouping-separator="," grouping-size="3"/>
<xsl:text>. </xsl:text>
<xsl:value-of select="title"/>
<xsl:text>&#xA;</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:transform>

Sonuç

1,000. Alfa Romeo
1,001. Bentley
1,002. Chevrolet
1,003. Dodge
1,004. Eagle
1,005. Ford
1,006. GMC
1,007. Honda
1,008. Isuzu
1,009. Mercedes
1,010. Nash
1,011. Opel
1,012. Pontiac
1,013. Toyota

Diğer Elementler

<xsl:import href=”diger-xsl-dosyasi.xsl”/> : Stylesheet’e başka bir stylesheet dosyasının içeriğini import eder.

<xsl:call-template name=”template-adi” (Bu nitelikteki isim ile template çağırılır)>: Template çağıtırılmak için kullanılır.

<xsl:param name=”referans-adi”>: Global ya da lokal olarak değişken tanımlar. <xsl:template> etiketinin içinde child elementler tarafından kullanılması için önce yazılmalıdır.

<xsl:with-param name=”parametre-adi” >: <xsl:apply-template> ya da <xsl:call-template> elementlerinin içinde kullanılır. Template çağırıldığında parametreye değer atanır. Kullanım örneği;

<xsl:call-template name=”tanımlanmis-tema”>
<xsl:with-param name="tanımlanmis-parametre">
<!-- Tema çalışması burada gerçekleşir -->
</xsl:with-param>
</xsl:call-template>
<xsl:template name="tanımlanmis-tema">
<xsl:param name="tanımlanmis-parametre"/>
<!-- Temanın geri kalanı burada çalışır -->
<xsl:template>

Ek olarak, XSLT 3.0 ile JSON doküman formatlanarak çıktısı XML olarak alınabilir. Belleğe sığamayacak kadar büyük dokümanları işlemek için XSLT 3.0'nin streaming desteği bulunur.

Kaynaklar

  • Watt, A.(2002). XPath Essentials. New York:John Wiley & Sons, Inc.
  • Tidwell, D.(2008). XSLT. USA:O’Reilly
  • www.xml.com, “What is XSLT?” (Erişim Tarihi:26 Temmuz 2020)
  • www.w3schools.com,”XSLT Tutorial” (Erişim Tarihi:26 Temmuz 2020)
  • www.lenzconsulting.com, “how-xslt-works” (Erişim Tarihi:26 Temmuz 2020)

--

--