VB 9.0 i XML podrška
Kao što je Janko već napisao, u paketu sa ostalim API-jima, u LINQ kolekciji dolazi i LINQ to XML API koji omogućava veoma lak rad sa XML dokumentima. Sa tim novim API-jem ne dolazi samo standardna podrška za upite koji su integrisani u jezik (C#, VB.NET itd.), već i kompletno novi XML API koji donosi različitu koncepciju u radu sa XML podacima. Iako je Janko koristio samo C# u svojim primerima, jasno je da podrška za ovaj novi API postoji i u novoj verziji VB-a, VB-u 9.0.
Postoji, međutim, jedna bitna razlika. Tim koji je radio VB 9.0 je otišao korak dalje, i doveo podršku za XML u ovom jeziku na viši nivo uvođenjem xml literals podrške. Šta to znači?
Uzmimo jedan prost XML fragment, recimo da je mali XML dokument.
<characters>
<character name="James T. Kirk">
<rank>Captain</rank>
<vessel>Enterprise</vessel>
</character>
<character name="Jan-Luc Pickard">
<rank>Captain</rank>
<vessel>Enterprise-G</vessel>
</character>
</characters>
Ukoliko iskopiramo ovaj fragment u Visual Basic kod, i iskoristimo podršku za anonimne tipove, možemo da dobijemo sledeći VB kod:
Dim element = <characters>
<character name="James T. Kirk">
<rank>Captain</rank>
<vessel>Enterprise</vessel>
</character>
<character name="Jan-Luc Pickard">
<rank>Captain</rank>
<vessel>Enterprise-G</vessel>
</character>
</characters>
Od verzije 9.0 Visual Basic jezika, moguće je konstruisati XML dokumente u samom kodu, jer se XML tretira kao "građanin prvog reda". XML je sada tip podatka koji je ravnopravan String ili Int tipu podatka, recimo. Dakle, nije više potrebno koristiti DOM ili klase iz System.Xml namespace-a, moguće je prosto pisati XML unutar samog koda.
Naravno, potrebno je napomenuti još nekoliko sitnica, kao recimo koji je tip element promenljive iz prethodnog primera. Promenljiva element je tipa XElement, koji se nalazi u System.Xml.Linq namespace-u. Korišćenjem anonimnih tipova (koji će možda biti predmet nekog budućeg posta), možemo da izbacimo eksplicitnu deklaraciju promenljive.Naravno, ako želite, možete i da je dodate; rezultat će biti identičan.
Dim element As System.Xml.Linq.XElement
element = <characters>
<character name="James T. Kirk">
<rank>Captain</rank>
<vessel>Enterprise</vessel>
</character>
<character name="Jan-Luc Pickard">
<rank>Captain</rank>
<vessel>Enterprise-G</vessel>
</character>
</characters>
Rad sa XML dokumentima
Naravno, kompletan LINQ to XML API je dostupan u slučaju ovaknog kreiranja XML dokumenata. Nad njima se mogu raditi upiti, mogu se serijalizovati putem metoda iz XElement klase itd. Jankov primer sa dinamičkim generisanjem XML-a putem kombinovanja LINQ-to-SQL i LINQ to XML API-ja je i ovde sasvim moguće izvesti, samo što sintaksa postaje još "čistija" jer možete da koristite XML literals umesto eksplicitnih kreiranja XElement objekata. Recimo:
Dim stdc As StarTrekVBDataContext = New StarTrekVBDataContext("Data Source=zlatkom5;Initial Catalog=AllThingsDemo;Integrated Security=True")
Dim result = <?xml version="1.0" encoding="utf-8"?>
<characters>
<%= From i In stdc.Characters _
Order By i.Age _
Select _
<character>
<name><%= i.Name %></name>
<age><%= i.Age %></age>
<yearsservice><%= i.Service %></yearsservice>
<allegiance><%= i.Allegiance.Allegiance %></allegiance>
<rank><%= i.Rank %></rank>
</character> %>
</characters>
Naravno, ukoliko želimo da koristimo LINQ to XML da vršimo upite nad već postojećim i kreiranim XML dokumentom, i to je sasvim jednostavno:
Dim result = <?xml version="1.0" encoding="utf-8"?>
<captains>
<%= From c In result...<character> _
Where c.<rank>.Value.Trim() = "Captain" _
Select _
<captain>
<name><%= c.<name>.Value %></name>
<age><%= c.<age>.Value %></age>
<allegiance><%= c.<allegiance>.Value %></allegiance>
<rank><%= c.<rank>.Value %></rank>
</captain> %>
</captains>
Pristup elementima unutar XML dokumenata
Pored podrške za XML kao tip podataka, koja značajno olakšava konstrukciju XML dokumenata, VB 9.0 takođe donosi i XML properties koje značajno olakšavaju pristupanje delovima XML koda po određenim osama:
- Child osa (child axis) kojom možemo da pristupimo child elementima, npr.: element.<character> će pokupiti sve <characters> elemente iz element objekta.
- Osa atributa (attribute axis) kojom možemo da pristupimo atributu određenog elementa, npr.: character.@name će uzeti name atribut character elementa.
- Descendant axis kojom možemo da uzmemo sve "naslednike" (nikada nisam želeo da prevodim ovo, ali neka bude za sada) određenog elementa, bez obzira na to koliko su duboko u hijerarhiji, npr.: character...<rank> (da, to su 3 tačkice)
- Ekstenziju Value kojom možemo da uzmemo vrednost bilo kog elementa, recimo character.<rank>.Value.
Ukoliko uzmemo jedan fiktivni primer ASP.NET strane za koju želimo da vrati XML dokument kao output (recimo da bismo je iskoristili na jedan REST način), mogli bismo da iskoristimo sve gore navedeno, kao i malo LINQ-to-SQL upita, na sledeći način:
Protected Sub _Default_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim stdc As StarTrekVBDataContext = New StarTrekVBDataContext("Data Source=zlatkom5;Initial Catalog=AllThingsDemo;Integrated Security=True")
Dim query = From c In stdc.Characters _
Select c.Name, c.Age, c.Service, c.Allegiance, c.Rank
If Request.QueryString("all") IsNot Nothing Then
query = From a In query _
Where a.Allegiance.Allegiance = Request.QueryString("all") _
Select a.Name, a.Age, a.Service, a.Allegiance.Allegiance, a.Rank
End If
Dim result = <?xml version="1.0" encoding="utf-8"?>
<characters>
<%= From i In query.ToList _
Order By i.Age _
Select _
<character>
<name><%= i.Name %></name>
<age><%= i.Age %></age>
<yearsservice><%= i.Service %></yearsservice>
<allegiance><%= i.Allegiance.Allegiance %></allegiance>
<rank><%= i.Rank %></rank>
</character> %>
</characters>
If Request.QueryString("trans") IsNot Nothing Then
result = <?xml version="1.0" encoding="utf-8"?>
<captains>
<%= From c In result...<character> _
Where c.<rank>.Value.Trim() = "Captain" _
Select _
<captain>
<name><%= c.<name>.Value %></name>
<age><%= c.<age>.Value %></age>
<allegiance><%= c.<allegiance>.Value %></allegiance>
<rank><%= c.<rank>.Value %></rank>
</captain> %>
</captains>
End If
Response.Clear()
Response.ContentType = "text/xml"
Response.Output.Write(result.ToString())
Response.Flush()
Response.End()
End Sub
Ova strana će na kraju vratiti običan XML dokument preko HTTP protokola. Jedna od stvari koje je takođe korisno primetiti jeste Response.Output.Write(result.ToString())linija. Ukoliko bismo radili sa starim XmlDocument klasama, ToString() metod na instanci XmlDocument klase bi nam vratio puno kvalifikovano (fully qualified) ime klase. U slučaju novog API-ja, ToString() metod na XElement klasi vraća XML koji je sadržaj te instance, odnosno XML dokument koji smo napravili.
Toliko za ovaj (drugi) post i kratko prebiranje po novoj podršci za XML u Visual Basic-u 9.0. Ne zaborative, VB 9.0 dolazi "u paketu" sa .NET Framework-om 3.5 i Visual Studiom 2008.
Peace. Out.
BD.