by Piotrosz
22. July 2009
Prawdziwa siła szablonów ujawnia się wtedy, gdy dokument XML ma niespójną strukturę.
Oto przykład fragmentu takiego dokumentu XML:
Zespół QOTSA został założony w 1997 roku przez Josha Homme po rozpadzie grupy Kyuss.
Śpiewają: Josh Homme, Nick Oliveri i Mark Lanegan.
<Link Href="http://www.qotsa.com">Strona zespołu</Link>
Chodzi mi o to, że elementy takie jak <Band> czy <Link> mogą występować w dowolnej kolejności i liczbie oraz
mogą się dowolnie zagnieżdżać, a wspaniała transformacja XSL i tak odpowiednio dopasuje szablony!
W pliku xsl wystarczyło dopisać deklaracje szablonów:
<a href="{@Href}" target="_blank">
</a>
Zaaplikowałem te szablony przed wyświetleniem listy utworów:
Mój komentarz:
Oto link do pliku XML, w którym zmodyfikowałem komentarz do płyty, tak aby występowała tam zawartość mieszana:
RecordsMixedNodeContent.xml.
Link do pliku XSL:
RecordsMixed.xsl.
A oto wynikowy plik HTML.
Widać tam sformatowany komentarz.
by Piotrosz
17. July 2009
Trzeci przykład obrazuje zastosowanie szablonów.
Szablony umożliwiają czytelną organizację pliku xsl.
Deklaruje się je przy pomocy polecenia
xsl:template, a aplikuje się je
przy pomocy
xsl:apply-templates.
<?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 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xsl:version="2.0">
<head>
<title>Przykład 3 - próba zastosowania szablonów</title>
<link rel="stylesheet" href="../Records.css" />
</head>
<body>
<h1>Moja kolekcja płyt</h1>
<xsl:apply-templates select="CdCollection/Album"></xsl:apply-templates>
</body>
</html>
</xsl:template>
<xsl:template match="/CdCollection/Album">
<span class="CdRecordArtist">
<xsl:value-of select="Artist"></xsl:value-of>
</span>
<span class="CdRecordTitle">
<xsl:value-of select="Title"></xsl:value-of>
</span>
<br/>
<br/>
<img src="{Cover}"/>
<br/>
<br/>
Lista utworów:
<ol>
<xsl:apply-templates select="Tracks/Track"></xsl:apply-templates>
</ol>
<br/>
</xsl:template>
<xsl:template match="/CdCollection/Album/Tracks/Track">
<li>
<xsl:value-of select="."></xsl:value-of>
<i>[<xsl:value-of select="@Time"></xsl:value-of>]</i>
</li>
</xsl:template>
</xsl:stylesheet>
Link do pliku XML
A oto wynik!
by Piotrosz
17. July 2009
Drugi przykład transformacji XSLT.
Mój przykładowy plik xml:
<?xml version="1.0" encoding="UTF-8"?>
Franks Wild Years
Tom Waits
http://upload.wikimedia.org/wikipedia/en/e/eb/Franks_cover.jpg
Experimental
Jazz
Mój komentarz
Songs For The Deaf
Queens Of The Stone Age
http://www.lyricblender.com/album_art/43169_songs-for-the-deaf.jpg
Hard rock
Moja transformacja tym razem zawiera dyrektywę xsl:for-each, która pozwala iterować po węzłach wybranych zapytaniem XPath przy użyciu
polecenia select. Widać też tutaj polecenie w nawiasach: {Ścieżka XPath} - jest to sposób na wstawienie wartości do atrybutu
(
attribute value template), jego działanie jest podobne do xsl:value-of select="Ścieżka XPath".
<html xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xsl:version="2.0">
<head>
<title>Przykład 2 - moja kolekcja płyt</title>
<link rel="stylesheet" href="../Records.css" />
</head>
<body>
Moja kolekcja płyt
<img src="{Cover}" alt="Okładka płyty {Title}" />
</body>
</html>
A oto wynik!
by Piotrosz
16. July 2009
Pierwszy przykład związany z tranformacjami XSLT, których chciałbym się nauczyć.
Moje tranformacje będę testował przy pomocy programiku, który zamieszczam poniżej.
Należy mu podać nazwę wejściowych plików .xsl i .xml, a on dokona tranformacji i zapisze wynikowy plik .html.
Programik ten zakłada, że nazwy wejściowych plików .xsl i .xml są takie same (np. Zaba.xml i Zaba.xsl). Jako nazwę można wtedy podać "Zaba" (lub "001\Zaba" jeśli pliki są w podkatalogu o nazwie "001").
Dodatkowo program zapisuje w isolated storage ostatnio podaną nazwę, dzięki czemu nie trzeba zawsze wpisywać tej nazwy, tylko wcisnąć ENTER,
jeśli chce się wczytać ostatnio wpisane pliki.
using System;
using System.Xml;
using System.Xml.Xsl;
using System.IO.IsolatedStorage;
using System.IO;
namespace XSLProcessor
{
class Program
{
static void Main()
{
XslCompiledTransform XslTransform = new XslCompiledTransform();
Console.WriteLine("Podaj nazwę pliku XML i XSL (bez rozszerzenia):");
string FileName = Console.ReadLine();
if (FileName == string.Empty)
FileName = ReadName();
try
{
SaveName(FileName);
XslTransform.Load(string.Concat(FileName, ".xsl"));
XslTransform.Transform(string.Concat(FileName, ".xml"), string.Concat(FileName, ".html"));
}
catch (XsltException ex)
{
Console.WriteLine("Przechwycono wyjątek XSLT: {0}", ex.Message);
Console.WriteLine(ex.InnerException);
Console.WriteLine("Line No: {0} Line position: {1}.", ex.LineNumber, ex.LinePosition);
}
catch (XmlException ex)
{
Console.WriteLine("Przechwycono wyjątek XML: {0}", ex.Message);
Console.WriteLine(ex.InnerException);
}
catch (IOException ex)
{
Console.WriteLine("Przechwycono wyjątek IO: {0}", ex.Message);
}
}
static void SaveName(string Name)
{
IsolatedStorageFileStream DataFile = new IsolatedStorageFileStream("XsltProcessorData.dat", FileMode.Create);
StreamWriter WriteStream = new StreamWriter(DataFile);
WriteStream.WriteLine(Name);
WriteStream.Flush();
WriteStream.Close();
DataFile.Close();
}
static string ReadName()
{
IsolatedStorageFileStream DataFile = new IsolatedStorageFileStream("XsltProcessorData.dat", FileMode.Open);
StreamReader ReadStream = new StreamReader(DataFile);
string Name = ReadStream.ReadLine();
ReadStream.Close();
DataFile.Close();
return Name;
}
}
}
Stworzyłem przykładowy plik XML, na którym przetestuję pierwszą transformację typu "hello world":
<?xml version="1.0" encoding="ISO-8859-2"?>
Żółta żaba
A tak wygląda moja tranformacja:
<?xml version="1.0" encoding="ISO-8859-2"?>
<html xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xsl:version="2.0">
<head>
<title>Pierwszy przykład</title>
</head>
<body>
</body>
</html>
A oto wynik!
by Piotrosz
10. July 2009
Przydatne właściwości kontrolki UpdatePanel, o których warto pamiętać:
DisplayMode
Block - wtedy UpdatePanel renderuje się wewnątrz <div id="UpdatePanel1"></div>, UpdatePanel łamie wtedy linię. Jest to
domyślne ustawienie.
Inline - wtedy UpdatePanel renderuje się wewnątrz <span id="UpdatePanel1"></span>;
UpdateMode
Always - wszystkie UpdatePanele odświeżają się przy każdym post backu. Jest to domyślne ustawienie. Jest ono zazwyczaj niekorzystne,
gdy na stronie jest wiele UpdatePaneli, bo powoduje, że strona działa wolniej!
Conditional - odświeża się tylko ten UpdatePanel, wewnątrz którego jest kontrolka, która spowodowała post back lub do którego jest
przypisany odpowiedni trigger.