LINQ to XML - co s chybějícím atributem   otázka

VB.NET

Dobrý den.

Ačkoli jsem se snažil odpověď nalézt na MSDN i jinde, většina příkladů je v C# a zrovna tohle nejsem schopný přepsat do VB.

Jde o to, že bych potřeboval udělat SELECT nad XML a získat z něj hodnotu atributu (mimo jiné), který není povinný, tudíž v některých řádcích je a v jiných není:

Dim CenikXML As XElement = XElement.Load("cenik.xml")

        Dim products = _
        From product In CenikXML.Descendants("Product") _
        Select _
        Kod = product.Attribute("Code").Value, _
        Nazev = product.Attribute("Name").Value, _
        Cena = product.Attribute("PriceDea").Value, _
        PartNumber = product.Attribute("PartNo").Value

No a třeba atribut PartNo není povinný, tudíž to vyvolá chybu

System.NullReferenceException was unhandled

Message="Odkaz na objekt není nastaven na instanci objektu."

Source="ZpracujCeniky"

StackTrace:

v ZpracujCeniky.Zpracuj._Lambda$1(XElement product) v D:\Projects\ZpracujCeniky\ZpracujCeniky\Zpracuj.vb:řádek 25 v System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() v ZpracujCeniky.Zpracuj.ZpracujCenikI6(String& odkoho, Int32& odkohoref) v D:\Projects\ZpracujCeniky\ZpracujCeniky\Zpracuj.vb:řádek 49 v ZpracujCeniky.Zpracuj.Main() v D:\Projects\ZpracujCeniky\ZpracujCeniky\Zpracuj.vb:řádek 4 v System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) v System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) v Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() v System.Threading.ThreadHelper.ThreadStart_Context(Object state) v System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) v System.Threading.ThreadHelper.ThreadStart()

InnerException:

a zhavaruje to právě na položce, kde ten atribut (např. ten PartNo) z důvodu nepovinnosti chybí.

A tady je to, co jsem našel v C# a zřejmě to je ono:

IEnumerable<Person> persons =

from e in x.Descendants("Person")

select new Person {

Name = e.Value,

Age = (int?)e.Attribute("Age") ?? 21

};

čili, když atribut Age chybí, je přiřazena hodnota 21...

Nenapadl mně způsob, jak napřed ten dotaz otestovat. Chápu, že bych to měl řešit pomocí Try...Catch, ale nenapadá mně jak. Jedině pokud to hodí chybu, tak že ten SELECT pošlu znovu bez toho vyžádání PartNo.

Posune někdo začátečníka?

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

Tak sice jsem nestačil nastudovat, jaký je rozdíl mezi Attribute a @, ale je fakt, že tenhle kód nekolabuje:

Dim CenikXML As XElement = XElement.Load("cenik.xml")

        Dim products = _
        From product In CenikXML...<StoItem> _
        Select Kod = product.@Code, _
        Nazev = product.@Name, _
        Cena = product.@PriceDea, _
        PartNumber = product.@PartNo

Byl bych rád, kdyby mi nějací chytřejší lidé zde vysvětlili, v čem je tak zásadní rozdíl oproti tomu původnímu kódu:

Dim CenikXML As XElement = XElement.Load("cenik.xml")

        Dim products = _
        From product In CenikXML.Descendants("Product") _
        Select _
        Kod = product.Attribute("Code").Value, _
        Nazev = product.Attribute("Name").Value, _
        Cena = product.Attribute("PriceDea").Value, _
        PartNumber = product.Attribute("PartNo").Value

Děkuji.

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