Načtení z XML do Comboboxů   otázka

VB.NET

Prosím o pomoc, mám něco jako .ini soubor x XML...pro jednoduchost uvádím část struktury:

<?xml version="1.0" encoding="utf-8"?>
<prehled_kategorii>
  <kat id="1" nazev="BBQ">
    <podkat id="1" nazev="Pevné podpalovače" />
    <podkat id="2" nazev="Tekuté podpalovače" />
    <podkat id="3" nazev="Gelové podpalovače" />
    <podkat id="4" nazev="LAO" />
    <podkat id="5" nazev="Paliva do biokrbů" />
    <podkat id="6" nazev="Uhlí a brikety" />
    <podkat id="7" nazev="Ostatní sortiment" />
  </kat>
  <kat id="2" nazev="Technické kapaliny">
    <podkat id="1" nazev="Lihy" />
    <podkat id="2" nazev="Aceton" />
    <podkat id="3" nazev="Toluen" />
    <podkat id="4" nazev="Xylen" />
    <podkat id="5" nazev="Technické benzíny" />
    <podkat id="6" nazev="Lakové benzíny" />
    <podkat id="7" nazev="Petrolej D" />
    <podkat id="8" nazev="Petrolej techn." />
    <podkat id="9" nazev="Benzínové čističe" />
    <podkat id="10" nazev="Toluenové čističe" />
    <podkat id="11" nazev="Ostatní látky" />
    <podkat id="12" nazev="Ostatní směsi" />
  </kat>
</prehled_kategorii>

Nyní podle článku p.Hercega (jinak děkuji za něj) naplním Combobx položkami "kat":

ComboBox2.Items.Clear()
For Each n As Xml.XmlNode In nastaveni.SelectNodes("/prehled_kategorii/kat")
ComboBox2.Items.Add(n.Attributes("nazev").Value)
Next n
ComboBox2.Text = ComboBox2.Items.Item(0)

a nyní bych potřeboval v závislosti na volbě z Comboboxu2 naplnit odpovídajícími položkami druhý Combobox6. Tedy třeba zvolím položku "Technické kapaliny" do duhého combobxu bych potřeboval naplinit podkategorie (seznam "podkat") tedy "Lihy, Aceton, Toluen...atd.). Obecně řečeno zviolím-li kat, potřebuju vyplnit příslušné podkat, které ve vybrané kat jsou.

Mám kód, který je špatně, ale nejsem schopný se hnout z místa:

Private Sub ComboBox2_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox2.SelectedIndexChanged

Dim hod As String = ComboBox2.Text
ComboBox6.Items.Clear()
For Each n As Xml.XmlNode In nastaveni.SelectNodes("/prehled_kategorii/kat")
If hod = n.Attributes("nazev").Value Then
For Each m As Xml.XmlNode In nastaveni.SelectNodes("/prehled_kategorii/kat/podkat")
                        ComboBox6.Items.Add(m.Attributes("nazev").Value)
Next
ComboBox6.Text = ComboBox6.Items.Item(0)
End If
Exit For
Next
End Sub

Tenhle kód tam naplní všechny podkat bez ohledu z jaké kat pocházejí. Já potřebuji zvolit LkatL a do do druhého comboboxu dát jen příslušné "podkat", nikoliv všechny "podkat". Snad jsem to vyjádřil srozumitelně.. prosím jak to udělat?

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

To, co hledáte je asi podmínka v XPath, která vybere pouze prvek, který jste specifikoval prvním ComboBoxem. Mohlo by jít o něco takového:

nastaveni.SelectNodes("/prehled_kategorii/kat[@id=" & <id kategorie> & "]/podkat")

Doporučuji však nepoužívat XmlDocument ale novější implementaci XML ve Visual Basicu - XDocument:

Module VbNet
  Sub Main()
    Dim source = <?xml version="1.0" encoding="utf-8"?>
                 <prehled_kategorii>
                   <kat id="1" nazev="BBQ">
                     <podkat id="1" nazev="Pevné podpalovače"/>
                     <podkat id="2" nazev="Tekuté podpalovače"/>
                     <podkat id="3" nazev="Gelové podpalovače"/>
                     <podkat id="4" nazev="LAO"/>
                     <podkat id="5" nazev="Paliva do biokrbů"/>
                     <podkat id="6" nazev="Uhlí a brikety"/>
                     <podkat id="7" nazev="Ostatní sortiment"/>
                   </kat>
                   <kat id="2" nazev="Technické kapaliny">
                     <podkat id="1" nazev="Lihy"/>
                     <podkat id="2" nazev="Aceton"/>
                     <podkat id="3" nazev="Toluen"/>
                     <podkat id="4" nazev="Xylen"/>
                     <podkat id="5" nazev="Technické benzíny"/>
                     <podkat id="6" nazev="Lakové benzíny"/>
                     <podkat id="7" nazev="Petrolej D"/>
                     <podkat id="8" nazev="Petrolej techn."/>
                     <podkat id="9" nazev="Benzínové čističe"/>
                     <podkat id="10" nazev="Toluenové čističe"/>
                     <podkat id="11" nazev="Ostatní látky"/>
                     <podkat id="12" nazev="Ostatní směsi"/>
                   </kat>
                 </prehled_kategorii>

    ' kategorie
    source.<prehled_kategorii>.<kat>.ToList().ForEach(Sub(k) Console.WriteLine(k.@id & ": " & k.@nazev))
    Console.WriteLine()

    Dim index As Integer
    Console.WriteLine("Id: ")
    Integer.TryParse(Console.ReadLine(), index)

    ' podkategorie
    source.<prehled_kategorii>.<kat>.Where(Function(k) k.@id = index.ToString()).<podkat>.ToList().ForEach(Sub(p) Console.WriteLine(p.@id & ": " & p.@nazev))

    Console.ReadLine()
  End Sub
End Module

Ze souboru lze vytvořit instanci třídy XDocument pomocí metody XDocument.Load.

Jak vidíte, kód se zjednoduší. Snadno získáte seznam kategorií (který můžete do ComboBoxu naplnit třeba přes vlasnost DataSource).

' Form.Load
ComboBox1.DataSource = source.<prehled_kategorii>.<kat>
' ComboBox1.SelectedItemChanged
ComboBox2.DataSource = source.<prehled_kategorii>.<kat>.Where(Function(k) k.@id = DirectCast(ComboBox1.SelectedItem, XElement).@id).<podkat>

Lze použít také indexer, ale ten ve Vašem případě použít nelze, protože id kategorií nekorespondují s jejich pořadími. Pro zajímavost však:

source.<prehled_kategorii>.<kat>(2).<podkat>

By vracelo podkategorie třetí (z pohledu pořadí umístění v DOM) kategorie.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Myslel jste to takhle...?

Dim hod As String = ComboBox2.Text
ComboBox6.Items.Clear()
For Each n As Xml.XmlNode In nastaveni.SelectNodes("/prehled_kategorii/kat[@jmeno=" & hod & "]/podkat")
ComboBox6.Items.Add(n.Attributes("nazev").Value)
Next
ComboBox6.Text = ComboBox6.Items.Item(0)
End If

Nefunguje, Combobox6 je prázdný a skončím s chybou na příkazu:

ComboBox6.Text = ComboBox6.Items.Item(0)

Co je špatně...?

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Pokud se rozhodnete vyhledávat element podle jména a nikoliv podle číselného id, budete muset hodnoty uzavřít do jednoduchých uvozovek:

"/prehled_kategorii/kat[@jmeno='" & hod & "']/podkat"

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Děkuji za snahu, ale stejně je druhý combobox prázdný. Je to analogické jako SQL, čili tento přípaz by měl vybrat všechny položky s podkat, kde je kat rovna danému textu (hod). Opravil jsem to na:

For Each n As Xml.XmlNode In nastaveni.SelectNodes("/prehled_kategorii/kat[@jmeno='" & hod & "']/podkat")

ale textbox 1 je naplněný, tam je to v pořádku, ale ten závislý zůstává prázdný...

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Jsem blbej... identifikátor není jméno, ale název!

Tohle funguje

For Each n As Xml.XmlNode In nastaveni.SelectNodes("/prehled_kategorii/kat[@nazev='" & hod & "']/podkat")

Moc děkuji, uzavřeno, pochopeno

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback