Aktuálně: Postihly zákazy tvou profesi? Poptávka po ajťácích prudce roste, využij podzimní akce 30% výuky zdarma!
Pouze tento týden sleva až 80 % na e-learning týkající se JavaScript
JavaScript týden

7. diel - Čítanie XML Saxe v VB.NET

V minulom dieli nášho seriálu tutoriálov o VB.NET, Úvod do XML a zápis Saxe , sme si predstavili formát XML a ukázali si, ako pomocou SAXUM vytvoriť jednoduché XML.

Teraz na minulý diel nadviažeme a napíšeme si proces opačný, teda načítanie XML súboru s používateľmi a zostavenie príslušnej objektovej štruktúry (listu užívateľov).

Pre úplnosť si opäť uvedieme náš XML súbor soubor.xml:

<?xml version="1.0" encoding="utf-8"?>
<uzivatele>
  <uzivatel vek="22">
    <jmeno>Pavel Slavík</jmeno>
    <registrovan>21.3.2000</registrovan>
  </uzivatel>
  <uzivatel vek="31">
    <jmeno>Jan Novák</jmeno>
    <registrovan>30.10.2012</registrovan>
  </uzivatel>
  <uzivatel vek="16">
    <jmeno>Tomáš Marný</jmeno>
    <registrovan>12.1.2011</registrovan>
  </uzivatel>
</uzivatele>

A naši triedu Uzivatel.vb:

Public Class Uzivatel
    Private _jmeno As String
    Public Property Jmeno As String
        Get
            Return _jmeno
        End Get
        Private Set(ByVal value As String)
            _jmeno = value
        End Set
    End Property

    Private _vek As Integer
    Public Property Vek As Integer
        Get
            Return _vek
        End Get
        Set(ByVal value As Integer)
            _vek = value
        End Set
    End Property

    Private _registrovan As DateTime
    Public Property Registrovan As DateTime
        Get
            Return _registrovan
        End Get
        Set(ByVal value As DateTime)
            _registrovan = value
        End Set
    End Property

    Public Sub New(jmeno As String, vek As Integer, registrovan As DateTime)
        Me.Jmeno = jmeno
        Me.Vek = vek
        Me.Registrovan = registrovan
    End Sub

    Public Overrides Function ToString() As String
        Return Me.Jmeno
    End Function
End Class

Založme si nový projekt, pôjde opäť o konzolovú aplikáciu. Pomenujeme ju XmlSaxCteni a do zložky bin / debug nakopírujeme náš XML súbor. K projektu pripojíme tiež triedu Uzivatel. Užívateľa budeme chcieť načítať do nejakej kolekcie, vytvorme si teda prázdny hárok uzivatele. Kód budeme kvôli jednoduchosti písať do metódy Main, ako to urobiť dobre objektovo sme si v tejto sekcii už ukazovali.

Dim uzivatele As New List(Of Uzivatel)

Čítanie XML cez SAX

Na čítanie XML cez SAX nám .NET framework poskytuje triedu XmlReader. Poďme si vytvoriť jej inštanciu. Ako tomu bolo pri triede XmlWriter, aj tu na to využijeme továrenské metódy Create, ktorej parametrom je názov súboru. Nezabudneme do Imports pripísať System.Xml. Všetko bude v bloku using, ktorý sa nám postará o uzavretí súboru:

Using xr As XmlReader = XmlReader.Create("soubor.xml")

End Using

Pripravíme si pomocné premenné pre vlastnosti používateľa. Nemôžeme ukladať priamo do inštancie, pretože vlastnosti sú read-only. Druhou možnosťou môže byť povoliť modifikáciu zvonka, tým ale strácame časť zapuzdrenie. Vlastnosti naplníme východiskovými hodnotami, tie sa dosadí v prípade, že daná hodnota nebude v XML zapísaná. Budeme potrebovať niekam ukladať meno aktuálneho elementu, k tomu si zadefinujeme stringové premennú element. Kód píšeme pochopiteľne do using bloku.

Dim jmeno As String = ""
Dim vek As Integer = 0
Dim registrovan As DateTime = DateTime.Now
Dim element As String = ""
Tento výukový obsah pomáhajú rozvíjať nasledujúce firmy, ktoré možno hľadajú práve teba!

Začneme načítať súbor. XmlReader načíta súbor riadok po riadku, zhora nadol. Na jeho inštanciu voláme metódu Read. Tá nám pri každom zavolaní načíta ďalšia tzv. Uzol. Uzlom môže byť element, prípadne atribút alebo textová hodnota elementu (nás bude zaujímať Element, Text a EndElement), ďalším typom uzla môže byť napr. Komentár, ktoré pre nás teraz nebudú dôležité. Ak je čítačka na konci súboru, vráti metóda read false, v opačnom prípade vracia true. Postúpime teda k postupnému načítanie všetkých uzlov v dokumente pomocou while cyklu:

While xr.Read()

End While

Na inštanciu XmlReader máme niekoľko užitočných vlastností, budeme používať NodeType, v ktorej je uložený typ aktuálneho uzla, na ktorom sa čítačka nachádza. Ďalej použijeme vlastnosti Name a Value, v ktorých je uložené meno aktuálneho uzla a jeho hodnota (ak nejakú má).

Nás budú teraz zaujímať 2 typy uzlov, Element a Text. Poďme na ne reagovať, zatiaľ napíšeme prázdne podmienky:

If xr.NodeType = XmlNodeType.Element Then
End If

Teraz vložíme kód do prvej podmienky. Budeme teda reagovať na načítanie elementu. Je tu potreba vykonať 2 akcie.

Kľúčovou akciou bude uloženie názvu elementu do premennej element. Tak budeme vzápätí schopní v druhej podmienke zistiť, ktorého elementu je text, ktorý práve čítame.

Zakaždým, keď narazíme na element uzivatel, načítame atribút vek pomocou metódy GetAttribute (), ktorej parametrom je názov atribútu. Atribút aktuálneho elementu možné načítať takto jednoducho. S hodnotou to tak jednoduché nie je, síce existujú metódy ReadContentAsTyp, ale pozor, tých z nevysvetliteľného dôvodu vykonajú Read a tak rozbijú beh while cyklu. V nezanořených XML by čítačka nefungovala správne. Nejakú dobu som sa snažil problém vyriešiť, ale riešenie bola natoľko krkolomná, že som došiel k záveru ReadContentAs vôbec nepoužívať. Obsah prvej podmienky teda bude vyzerať takto:

If xr.NodeType = XmlNodeType.Element Then
    element = xr.Name
    If element = "uzivatel" Then
        vek = xr.GetAttribute("vek")
    End If
ElseIf xr.NodeType = XmlNodeType.Text Then
End If

Prejdime do ďalšej vetvy, teda do spracovania hodnoty elementu. Tu využijeme vopred uložené hodnoty názvu elementu, ktorú si vložíme do Select Case. Podľa elementu uložíme hodnotu do danej vlastnosti užívateľa:

Select Case element
    Case "jmeno"
        jmeno = xr.Value
    Case "registrovan"
        registrovan = DateTime.Parse(xr.Value)
End Select

Už sme veľmi blízko, bystrejší si iste všimli, že používateľa nikde nepridávame. Jeho pridanie nastane vo chvíli načítanie uzatváracieho elementu uzivatel. K našim dvom podmienkam teda pridáme tretí:

' načítáme konec elementu
ElseIf xr.NodeType = XmlNodeType.EndElement And xr.Name = "uzivatel" Then
    uzivatele.Add(New Uzivatel(jmeno, vek, registrovan))

máme hotovo :)

Pre istotu prikladám kompletnú kód načítanie súboru:

Using xr As XmlReader = XmlReader.Create("soubor.xml")
    Dim jmeno As String = ""
    Dim vek As Integer = 0
    Dim registrovan As DateTime = DateTime.Now
    Dim element As String = ""

    While xr.Read()
        If xr.NodeType = XmlNodeType.Element Then
            element = xr.Name
            If element = "uzivatel" Then
                vek = xr.GetAttribute("vek")
            End If
        ElseIf xr.NodeType = XmlNodeType.Text Then
            Select Case element
                Case "jmeno"
                    jmeno = xr.Value
                Case "registrovan"
                    registrovan = DateTime.Parse(xr.Value)
            End Select
        ElseIf xr.NodeType = XmlNodeType.EndElement And xr.Name = "uzivatel" Then
            uzivatele.Add(New Uzivatel(jmeno, vek, registrovan))
        End If
    End While
End Using

Zostáva užívateľa vypísať, aby sme vedeli, že sme ich načítali správne. Upravíme si metódu toString () v triede Uzivatel tak, aby vypisovala všetky hodnoty:

Public Overrides Function ToString() As String
    Return String.Format("{0}, {1}, {2}", Jmeno, Vek, Registrovan.ToShortDateString())
End Function

Užívateľa jednoducho vypíšeme:

' výpis načtených objektů
For Each u As Uzivatel In uzivatele
    Console.WriteLine(u)
Next
Console.ReadKey()

a výsledok:

Výsledok načítanie objektov z XML Saxe v Visual Basic .NET

Ak sa vám načítanie príliš nepáčilo, dám vám za pravdu. Kým generovanie nového XML súboru je Saxe veľmi jednoduché a prirodzené, načítanie je naozaj krkolomné.

Nabudúce, Práca s XML súbory pomocou DOM vo VB.NET , sa pozrieme na DOM, teda objektový prístup k XML dokumentu.


 

Stiahnuť

Stiahnuté 162x (67.87 kB)
Aplikácia je vrátane zdrojových kódov v jazyku VB

 

Predchádzajúci článok
Úvod do XML a zápis Saxe
Všetky články v sekcii
Súbory a sieť vo Visual Basic .NET
Článok pre vás napísal Michal Žůrek - misaz
Avatar
Ako sa ti páči článok?
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje tvorbě aplikací pro počítače, mobilní telefony, mikroprocesory a tvorbě webových stránek a webových aplikací. Nejraději programuje ve Visual Basicu a TypeScript. Ovládá HTML, CSS, JavaScript, TypeScript, C# a Visual Basic.
Aktivity (1)

 

 

Komentáre

Avatar
koncelikj
Člen
Avatar
koncelikj:10.5.2015 21:34

Hmm. A jak zachytit chybu, že soubor neexistuje? Popis na MSDN je na mě moc vědecký.

 
Odpovedať
10.5.2015 21:34
Avatar
Odpovedá na koncelikj
Michal Žůrek - misaz:10.5.2015 21:54

toto se neošetřuje jako chyba ale ošetřuje se to ještě před načítáním souboru podmínkou.

If Not System.IO.File.Exists(cestaKSouboru) Then
    ' soubor neexistuje
End If
 
Odpovedať
10.5.2015 21:54
Avatar
Josef Jeništa:17.3.2017 1:38

Na konci souboru jsme měl posledního člena 2x. Kód jsem trochu upravil. Po přidání uživatele jsem element vymazal (element = "") a teď to chodí, jak má. Omlouvám se, nevím jak se tady upravuje zdroják, aby to nebylo vše na levé straně.

Dim uzivatele As New List(Of Uzivatel)
Dim poc As Integer = 0
Using xr As XmlReader = XmlReader.Cre­ate("soubor.xml")
Dim jmeno As String = ""
Dim vek As Integer = 0
Dim registrovan As DateTime = DateTime.Now
Dim element As String = ""

While xr.Read()
If xr.NodeType = XmlNodeType.Element Then
element = xr.Name
If element = "uzivatel" Then
vek = xr.GetAttribu­te("vek")
ElseIf element = "uzivatele" Then
poc += 1
End If

ElseIf xr.NodeType = XmlNodeType.Text Then
Select Case element
Case "jmeno"
jmeno = xr.Value
Case "registrovan"
registrovan = DateTime.Parse(xr­.Value)
End Select

ElseIf (xr.NodeType = XmlNodeType.En­dElement) And (element = "registrovan") Then
If poc <> 2 Then
uzivatele.Add(New Uzivatel(jmeno, vek, registrovan))
element = ""
End If
End If
End While
End Using

Odpovedať
17.3.2017 1:38
Kolik jazyků umíš, tolikrát jsi programátorem.
Tento výukový obsah pomáhajú rozvíjať nasledujúce firmy, ktoré možno hľadajú práve teba!
Avatar
Josef Jeništa:17.3.2017 1:41

Zapomněl jsem ze zdrojáku vyhodit načítání do poc (poc += 1) a dotaz na poc <> 2. Dal jsem si to tam kvůli ladění.

Odpovedať
17.3.2017 1:41
Kolik jazyků umíš, tolikrát jsi programátorem.
Avatar
Odpovedá na Josef Jeništa
Michal Štěpánek:17.3.2017 7:36

... nevím jak se tady upravuje zdroják, aby to nebylo vše na levé straně.

Zdroják se vkládá za pomoci tagů "code" - je to to druhé tlačítko zleva, hned vedle smajlíka...

Odpovedať
17.3.2017 7:36
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Josef Jeništa:17.3.2017 16:46

Takhle je to definitivně.

Dim uzivatele As New List(Of Uzivatel)
    Dim poc As Integer = 0
    Using xr As XmlReader = XmlReader.Create("soubor.xml")
      Dim jmeno As String = ""
      Dim vek As Integer = 0
      Dim registrovan As DateTime = DateTime.Now
      Dim element As String = ""

      While xr.Read()
        If xr.NodeType.ToString <> "Whitespace" Then
          If xr.NodeType = XmlNodeType.Element Then
            element = xr.Name
            If element = "uzivatel" Then
              vek = xr.GetAttribute("vek")
            End If

          ElseIf xr.NodeType = XmlNodeType.Text Then
            Select Case element
              Case "jmeno"
                jmeno = xr.Value
              Case "registrovan"
                registrovan = DateTime.Parse(xr.Value)
            End Select

          ElseIf (xr.NodeType = XmlNodeType.EndElement) And (element = "registrovan") Then
            uzivatele.Add(New Uzivatel(jmeno, vek, registrovan))
            element = ""
          End If
        End If
      End While
    End Using

    For Each u As Uzivatel In uzivatele
      Console.WriteLine(u)
    Next
    Console.ReadKey()
Odpovedať
17.3.2017 16:46
Kolik jazyků umíš, tolikrát jsi programátorem.
Robíme čo je v našich silách, aby bola tunajšia diskusia čo najkvalitnejšia. Preto do nej tiež môžu prispievať len registrovaní členovia. Pre zapojenie sa do diskusie sa zaloguj. Ak ešte nemáš účet, zaregistruj sa, je to zadarmo.

Zobrazené 6 správy z 6.