<meta http-equiv='pics-label' content='(pics-1.1 "http://www.icra.org/ratingsv02.html" comment "ICRAonline EN v2.0" l gen true for "http://interval.cz" r (nz 1 vz 1 lz 1 oz 1 cz 1) "http://www.rsac.org/ratingsv01.html" l gen true for "http://interval.cz" r (n 0 s 0 v 0 l 0))' />
<h2>Zpracovßnφ databßzov²ch dat p°es XSLT v ASP</h2>
<p id='prepend'>Ka₧d² ASP programßtor jist∞ znß obvykl² zp∙sob psanφ webov²ch databßzov²ch aplikacφ, p°i kterΘm se p°ipojφ k databßzi, spuÜt∞nφm dotazu zφskß data v Recordsetu, iteracφ je prochßzφ, zpracovßvß a slepuje po₧adovan² HTML k≤d. Modernφ doba vÜak po₧aduje trochu nov∞jÜφ a hlavn∞ robustn∞jÜφ p°φstup k prßci s daty za vyu₧itφ nov²ch prost°edk∙, jako jsou XML a XSLT. Jak uvidφte, tyto postupy jsou p°φstupnΘ i na dnes ji₧ p°e₧itΘ platform∞ ASP.</p>
<p>Tento Φlßnek voln∞ navazuje na p°edchozφ <a href='http://interval.cz/clanek.asp?article=3462' title='B°φza, Petr: XmlDataDocument a zobrazenφ stromovΘ struktury p°es XSLT v ASP.NET'>XmlDataDocument a zobrazenφ stromovΘ struktury p°es XSLT v ASP.NET</a>, ve kterΘm jsme °eÜili ·kol podobn², tentokrßt vÜak aplikaci postavφme na trochu starÜφ platform∞. Struktura databßzovΘ tabulky je stßle stejnß - je rozebrßna v p∙vodnφm Φlßnku, proto se k nφ nebudu vracet, mφsto toho se hned vrhneme na k≤d naÜφ aplikace, p°iΦem₧ budu poukazovat na nejd∙le₧it∞jÜφ rozdφly obou °eÜenφ.</p>
<h3>NaΦtenφ vstupnφch dat</h3>
<p>Prvnφm krokem je samoz°ejm∞ op∞t zφskßnφ dat, se kter²mi pak budeme pracovat. To znamenß p°ipojenφ k databßzi, vyvolßnφ dotazu a p°evedenφ dat do XML formßtu, kter² pot°ebujeme pro XSL transformaci. Jeliko₧ vÜak v ASP nemßme k dispozici takov² luxus jak² nabφzφ v .NETu t°φda <code>XmlDataDocument</code>, musφme najφt jin² zp∙sob zφskßnφ XML dokumentu z tabulky. Nebudeme vym²Ület ₧ßdnΘ krkolomnΘ zp∙soby a vyu₧ijeme komponentu <strong>SQLXML</strong>, kterß by nem∞la b²t na Microsoft SQL Serveru 2000 (a nov∞jÜφch) ₧ßdn² problΘm. OvÜem nep°edbφhejme!</p>
<p>K p°φstupu k dat∙m pou₧ijeme ADO a standardnφ OLEDB ovladaΦ. Komponenta SQLXML sice obsahuje takΘ specißlnφho poskytovatele <strong>SQLXMLOLEDB</strong>, kter² vlastn∞ pracuje nad p∙vodnφm SQLOLEDB (viz <a href='http://msdn.microsoft.com/library/en-us/sqlxml3/htm/clientsidexml_70bp.asp'>Architecture of Client-Side and Server-Side XML Formatting</a>), ovÜem pokud mßte webov² server odd∞len² od databßzovΘho, pravd∞podobn∞ tohoto poskytovatele k dispozici nemßte. To vÜak nevadφ, proto₧e s b∞₧n²m OLEDB si bez problΘm∙ vystaΦφme.</p>
<p>Dotaz pro databßzi bude obyΦejn² <samp>SELECT</samp> s dov∞tkem <samp>FOR XML AUTO</samp>, kter²m po₧ßdßme SQL server, aby nßm vrßtil v²sledek v XML formßtu.</p>
<br />cmd.CommandText = "SELECT * FROM diskuse FOR XML AUTO"
</div>
<p>Jak bude vypadat v²sledek takovΘho dotazu? M∙₧ete si to vyzkouÜet v Query Analyzeru, pokud jej mßte k dispozici. Zpracovßnφm dotazu vznikne fragment XML dokumentu jako dlouh² °et∞zec, kter² je pak rozd∞len po 256 znacφch do n∞kolika °ßdek jakΘsi fiktivnφ tabulky s jedin²m sloupcem. Zde ovÜem nastßvß menÜφ problΘm. Sloupec toti₧ nenφ °et∞zcovΘho typu (String), n²br₧ jsou to binßrnφ data, kterß jsou ve VBS reprezentovßny jako pole bajt∙ - Byte().</p>
<p>S tφmto datov²m typem se ve VBS velmi obtφ₧n∞ pracuje, museli bychom tedy ka₧d² °ßdek n∞jak²m zp∙sobem p°evΘst na °et∞zec a pak vÜechny °ßdky spojit dohromady. Existuje vÜak jednoduÜÜφ a takΘ v²konn∞jÜφ zp∙sob. V²sledek dotazu lze cel² najednou "nasypat" do takzvanΘho <em>streamu</em> a pak jej cel² p°eΦφst jako °et∞zec, se kter²m ji₧ lze snadno pracovat. Nejd°φve tedy musφme stream vytvo°it, otev°φt a propojit jej s naÜim objektem <samp>cmd</samp>.</p>
<p>VÜechno je p°ipraveno, tak₧e m∙₧eme p°φkaz spustit. P°itom musφme poskytovateli °φci, aby v²slednß data zapsal do p°ipojenΘho streamu, k Φemu₧ slou₧φ t°etφ parametr metody <strong>Execute</strong>, kterΘmu nastavφme hodnotu ADO konstanty <strong>adExecuteStream</strong>, tedy 1024. Ostatnφ parametry mohou z∙stat prßzdnΘ. PotΘ okam₧it∞ uzav°eme databßzovΘ p°ipojenφ, abychom zbyteΦn∞ neblokovali zdroje SQL serveru ostatnφm proces∙m.</p>
<div class='sample'>
cmd.Execute , , 1024
<br />conn.close
</div>
<p>Nynφ stream obsahuje kompletnφ v²sledek dotazu. P°esuneme se na jeho zaΦßtek, a naΦteme cel² jeho obsah jako °et∞zec do novΘho XML dokumentu. P°itom musφme jeho obsah uzav°φt do jedinΘho elementu, proto₧e se jednß o XML fragment, kter² m∙₧e obsahovat vφce XML element∙, avÜak XML dokument smφ mφt jen jeden ko°enov² element. NßÜ element si pojmenujeme p°φznaΦn∞ <samp>diskuse</samp>. K dobr²m mrav∙m pat°φ takΘ p°ipojenφ XML deklarace.</p>
<div class='sample'>
dim xml
<br />set xml = Server.CreateObject("MSXML2.DOMDocument")
<br />stream.Position = 0
<br />xml.LoadXML("<?xml version='1.0'?>" & _
<br /> "<diskuse>" & _
<br /> stream.ReadText & _
<br /> "</diskuse>")
</div>
<p>Je t°eba dßt pozor na chyby MS XML parseru, kter² nevyvolßvß v²jφmky, pouze si zapisuje p°φpadnΘ chyby do vlastnosti <samp>parseError</samp> dokumentu. Kdyby doÜlo k chyb∞, b∞h k≤du pokraΦuje normßln∞ dßle a chyba se projevφ n∞kde jinde, ovÜem pak se nßm m∙₧e skuteΦn² zdroj chyby hledat velice t∞₧ko. Proto tΘto situaci rad∞ji p°edejdeme a p°φpadnou chybu zpracujeme ihned na mφst∞ - v ukßzkovΘ aplikaci pouze vypφÜeme chybovou zprßvu a ukonΦφme skript.</p>
<div class='sample'>
if xml.parseError.errorCode <> 0 then
<br /> response.write "Error loading XML: " & _
<br /> xml.parseError.reason
<br /> response.end
<br />end if
</div>
<p>Dlu₧no dodat, ₧e pravd∞podobnost chyby parsingu je asi pom∞rn∞ nφzkß, proto₧e onen XML dokument nikdo "nelepφ ruΦn∞", ale je generovßn komponentou SQLXML, p°iΦem₧ lze jist∞ ·sp∞Ün∞ pochybovat o tom, ₧e by tato komponenta vytvß°ela nevalidnφ XML. OvÜem rozmary Microsoft produkt∙ nenφ nikdy dobrΘ podce≥ovat a kdy₧ u₧ nic jinΘho, alespo≥ testujeme, zda jsme v²sledek dotazu sprßvn∞ uzav°eli do ko°enovΘho elementu dokumentu.</p>
<p>XML dokument je p°ipraven. Jeho vnit°nφ strukturou jsme se zatφm nezab²vali, poj∩me to napravit. Budeme ji muset dob°e znßt, abychom pak sestavili dob°e fungujφcφ XSL transformaci. Zp∙sob, jak²m generuje server XML data, zßvisφ Φist∞ na pou₧itΘm dotazu. My jsme pou₧ili jeden ze zßkladnφch tvar∙ <samp>FOR XML AUTO</samp> a v takovΘm p°φpad∞ zφskßme dokument podobn² nßsledujφcφmu:</p>
<div class='sample'>
<?xml version="1.0"?>
<br /><diskuse>
<br /> <diskuse
<br /> ID="1"
<br /> autor="paya"
<br /> obsah="4all: Ahoj, jdeme na pivo?" />
<br /> <diskuse
<br /> ID="2"
<br /> pID="1"
<br /> autor="pierre"
<br /> email="ja@pierre.cz"
<br /> obsah="OK, v 19h na Stodolnφ?" />
<br /> ...
<br /></diskuse>
</div>
<p>V²slednß struktura je trochu odliÜnß od tΘ, kterß vznikß zpracovßnφm .NET t°φdou XmlDataDocument. Ka₧d² °ßdek tabulky se p°evede na XML element, jeho₧ nßzev je shodn² s nßzvem p∙vodnφ tabulky. Nejviditeln∞jÜφ zm∞nou je p°evod sloupc∙ na XML atributy mφsto XML element∙. NicmΘn∞ pokud bychom tou₧ili vφce po XML elementech, staΦφ zm∞nit dopln∞k naÜeho SQL dotazu na <samp>FOR XML AUTO, ELEMENTS</samp>. To vÜak jen tak na okraj. VÜimn∞te si, ₧e pole, kterß majφ v databßzovΘ tabulce hodnotu NULL, nejsou v dokumentu op∞t v∙bec vid∞t.</p>
<p>Dokument jsme si prohlΘdli, zb²vß jen naΦφst stylesheet provΘst transformaci a v²sledek vypustit na prohlφ₧eΦ klienta:</p>
<p>No a ·pln∞ nakonec napφÜeme stylesheet. Respektive staΦφ pou₧φt ukßzku z p∙vodnφho Φlßnku a upravit ji pro zpracovßnφ XML dokumentu s naÜφ mφrn∞ odliÜnou strukturou. FunkΦnost a v²sledek transformace z∙stanou naprosto toto₧nΘ.</p>
<p>K dispozici je vßm i <a href='podklady/briza/924/diskuse.zip'>ukßzkovß aplikace</a> ke sta₧enφ.</p>
<h3>Odkazy, zdroje</h3>
<div class='list'>
<ul>
<li><a href='http://interval.cz/clanek.asp?article=3462'>XmlDataDocument a zobrazenφ stromovΘ struktury p°es XSLT v ASP.NET</a> - B°φza, Petr (Interval.cz, 12. 7. 2004)</li>
<li><a href='http://interval.cz/clanek.asp?article=3226'>Generujeme XML z MS SQL Serveru</a> - B°φza, Petr (Interval.cz, 1. 4. 2004)</li>
<li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3476'>Kurz SVG - vypl≥ovßnφ I</a></li><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3479'>PPWizard - pokroΦilß makra, podmφnky a standardnφ definice</a></li><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3478'>Transformace dat z databßze pomocφ XSL v .NET jednoduÜe</a></li><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3481'>Strßnkovßnφ v ovlßdacφm prvku DataGrid bez pou₧itφ PostBack</a></li><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3477'>Zpracovßnφ databßzov²ch dat p°es XSLT v ASP</a></li>
</ul>
</div>
</div>
<div class='page-right-box cauldron'>
<h3>Diskuznφ kotel</h3>
<div class='page-right-box-in'>
<ul>
<li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3473' title='(25 komentß°∙)'>Sedφm na konßri a Φtu Computerworld</a></li><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3468' title='(23 komentß°∙)'>PPWizard - tvo°φme a spravujeme WWW strßnky</a></li><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3474' title='(22 komentß°∙)'>PφÜeme pro web - o sφle slov</a></li><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3464' title='(15 komentß°∙)'>Kurz SVG - grafickß primitiva</a></li><li><a href='http://interval.cz/__redirect/redirect.asp?what=interval_offline&url=http://interval.cz/clanek.asp?article=3472' title='(10 komentß°∙)'>Cryptography v .NET - Symmetric a Asymmetric encryption</a></li>