اساس کار XSLT
در تصویر زیر، فایل xml به همراه xslt، به تجزیه کننده یا تحلیل کننده داده میشوند. در این قسمت هر دو فایل منبع تحلیل شده و از روی فایل xml، درختی در حافظه تهیه میشود و از فایل xslt یک سری قوانین استخراج میشوند. بعد این دو محتوای جدید تولید شده، در اختیار XSL Processor قرار گرفته و از روی آنها به ساخت درخت نتیجه (نوع درخواستی) در حافظه میرسد که در نهایت آن را به نام یک فایل مستند میکند.
پروژه نمونه
در این مقاله ما یک فایل xml داریم که قصد داریم آلبومهایی را طبق ساختار زیر، در آن قرار دهیم و سپس بر اساس قوانین xslt آن را در قالب یک فایل html نشان دهیم. فایلهای تمرینی این مقاله در این آدرس قابل دسترسی است.
ساختار فایل xml:
<Albums> <Album> <name>Modern Talking</name> <cover>http://album.com/a.jpg</cover> <Genres> <Genre>POP</Genre> <Genre>Jazz</Genre> <Genre>Classic</Genre> </Genres> <Description> this is a marvelous Album </Description> <price> 25.99$ </price> </Album> </Albums>
در ابتدا فایل، برای معرفی فایل و رعایت قرارداد، فضای نام مربوطه را یا به شکل زیر
<xsl:stylesheet version="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/"> <html> .... </html> </xsl:template>
نمایش فیلدها
سپس در آن، کد html مورد نظر را وارد میکنیم و در میان این کدها، تگهای xslt را وارد مینماییم. کد زیر بخشی از صفحه هست که برای نمایش آلبومها استفاده میکنیم:
<div> <img src="" alt="image" /> <h3> <xsl:value-of select="albums/album/name" /> </h3> <h4>Artist Name 1</h4> <h5>POP</h5> <h6>25/5/2015</h6> <h7>this is description</h7> <div> <a href="#">More</a> </div> </div>
<xsl:for-each select="albums/album"> <div> <img src="" alt="image" /> <h3> <xsl:value-of select="name" /> </h3> <h4>Artist Name 1</h4> <h5>POP</h5> <h6>25/5/2015</h6> <h7>this is description</h7> <div> <a href="#">More</a> </div> </div> </xsl:for-each>
ایجاد ارتباط میان دو فایل XML و XSLT
برای اجرا و تست آن باید از طریق یک ابزار که توانایی تحلیل این دستورات را دارد، استفاده کنید. یکی از همین ابزارها، مرورگر شماست. برای اینکه به مرورگر ارتباط فایل xml و xsl را بفهمانیم، تکه کد زیر را در فایل xml جهت لینک شدن مینویسیم و سپس فایل xml را در مرورگر اجرا میکنیم:
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="index.xslt"?>
ساخت المان یا تگ
در ادامه بقیه فیلدها را تکمیل میکنیم. فیلد بعدی تصویر است که تصویر دیگر مانند متن، بین تگها قرار نمیگیرد و باید داخل attribute تگ تصویر درج شود. برای نمایش تصویر میتوانیم به دو شکل عمل کنیم. کد را به صورت زیر بنویسیم:
<img src="{cover}" width="200px" height="200px"> <xsl:value-of select="cover" /> </img>
<xsl:element name="img"> <xsl:attribute name="src"> <xsl:value-of select="cover"/> </xsl:attribute> <xsl:attribute name="width"> 200px </xsl:attribute> <xsl:attribute name="height"> 200px </xsl:attribute> <xsl:value-of select="cover"/> </xsl:element>
دستور العملهای بیشتر (مرتب سازی)
<xsl:for-each select="Albums/Album"> <xsl:sort select="name"/>
دستورات شرطی
حال تصمیم میگیریم که آلبومهای با قیمت بالاتر از 10 دلار را 2 دلار تخفیف دهیم. برای اینکار نیاز است تا با تگ if آشنا شویم:
<xsl:variable name="numprice" select="number(substring(price,1,string-length(price)-1))" /> <xsl:if test="$numprice>=10"> <h4 > <span style='text-decoration:line-through'> <xsl:value-of select="price" /> </span> <b> <xsl:value-of select="$numprice -2" />$ </b> </h4> </xsl:if>
<xsl:variable name="numprice" select="number(substring(price,1,string-length(price)-1))" /> <xsl:choose> <xsl:when test="$numprice>=10"> <h4 > <span style='text-decoration:line-through;color:red'> <xsl:value-of select="price" /> </span> <b> <xsl:value-of select="$numprice -2" />$ </b> </h4> </xsl:when> <xsl:otherwise> <b> <xsl:value-of select="$numprice" />$ </b> </xsl:otherwise> </xsl:choose>
استفاده از template ها
<xsl:template match="DateOfRelease"> <xsl:variable name="date" select="."/> <xsl:variable name="day" select="substring($date,1,2)"/> <xsl:variable name="month" select="number(substring($date,4,2))"/> <xsl:variable name="year" select="substring($date,7,4)"/> Release Date: <xsl:choose> <xsl:when test="$month = 1"> <xsl:value-of select="$day"/>,Jan/<xsl:value-of select="$year"/> </xsl:when> <xsl:when test="$month = 2"> <xsl:value-of select="$day"/>,Feb/<xsl:value-of select="$year"/> </xsl:when> <xsl:when test="$month = 3"> <xsl:value-of select="$day"/>,Mar/<xsl:value-of select="$year"/> </xsl:when> <xsl:when test="$month = 4"> <xsl:value-of select="$day"/>,Apr/<xsl:value-of select="$year"/> </xsl:when> <xsl:when test="$month = 5"> <xsl:value-of select="$day"/>,May/<xsl:value-of select="$year"/> </xsl:when> <xsl:when test="$month = 6"> <xsl:value-of select="$day"/>,Jun/<xsl:value-of select="$year"/> </xsl:when> <xsl:when test="$month = 7"> <xsl:value-of select="$day"/>,Jul/<xsl:value-of select="$year"/> </xsl:when> <xsl:when test="$month = 8"> <xsl:value-of select="$day"/>,Aug/<xsl:value-of select="$year"/> </xsl:when> <xsl:when test="$month = 9"> <xsl:value-of select="$day"/>,Sep/<xsl:value-of select="$year"/> </xsl:when> <xsl:when test="$month = 10"> <xsl:value-of select="$day"/>,Oct/<xsl:value-of select="$year"/> </xsl:when> <xsl:when test="$month = 11"> <xsl:value-of select="$day"/>,Nov/<xsl:value-of select="$year"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$day"/>,Dec/<xsl:value-of select="$year"/> </xsl:otherwise> </xsl:choose> </xsl:template>
<xsl:for-each select="Albums/Album"> <xsl:sort select="name"/> <div> <img src="{cover}" width="200px" height="200px"> <xsl:value-of select="cover" /> </img> <h3> <xsl:value-of select="name" /> </h3> <h4>POP</h4> <xsl:variable name="numprice" select="number(substring(price,1,string-length(price)-1))" /> <xsl:choose> <xsl:when test="$numprice>=10"> <h4 > <span style='text-decoration:line-through;color:red'> <xsl:value-of select="price" /> </span> <b> <xsl:value-of select="$numprice -2" />$ </b> </h4> </xsl:when> <xsl:otherwise> <h4 > <b> <xsl:value-of select="$numprice -2" />$ </b> </h4> </xsl:otherwise> </xsl:choose> <h4> <!-- محل صدا زدن قالب--> <xsl:apply-templates select="DateOfRelease"/> </h4> <h4> <xsl:value-of select="Description"/> </h4> <div> <a href="#">More</a> </div> </div> </xsl:for-each>
فیلترسازی
یکی از خصوصیات دیگری که فایل
XML داشت، فیلد ژانر موسیقی بود و قصد داریم با استفاده از فیلترسازی،
تنها سبک خاصی مثل سبک پاپ را نمایش دهیم و موسیقیهایی را که خارج از این سبک
هستند، از نتیجه حذف کنیم. به همین علت دستور for-each را به شکل زیر
تغییر میدهیم:
<xsl:for-each select="Albums/Album[contains(Genres/Genre, 'POP')]">
<xsl:for-each select="Albums/Album[not(contains(Genres/Genre, 'POP'))]">
<xsl:for-each select="Genres/Genre"> <xsl:value-of select="."/> <xsl:if test="position() != last()"> , </xsl:if> </xsl:for-each>
تبدیل xml و xsl در دات نت
string xmlfile = Application.StartupPath + "\\sampleXML.xml"; //بارگذاری فایل قوانین در حافظه XslTransform xslt = new XslTransform(); xslt.Load("sample-stylesheet.xsl"); //XPath ایجاد یک سند جدید بر اساس استاندارد XPathDocument xpath = new XPathDocument(xmlfile); //آماده سازی برای نوشتن فایل نهایی XmlTextWriter xwriter = new XmlTextWriter(xmlfile + ".html", Encoding.UTF8); //نوشتن فایل مقصد بر اساس قوانین مشخص شده xslt.Transform(xpath, null, xwriter, null); xwriter.Close();
XsltArgumentList xslArgs = new XsltArgumentList(); xslArgs.AddParam("logo", "", logo); xslArgs.AddParam("name", "", name); .... xslt.Transform(xpath, xslArgs, xwriter, null);