Linq to XML w aplikacji WP

Odpowiedz Nowy wątek
2015-01-03 00:15
Krwawy Lew
0

Witajcie,
Kiepski ze mnie programista, żeby nie powiedzieć ze żaden wiec proszę Was o pomoc.
Mam program który rozpoznaje kody kreskowe, korzysta z biblioteki ZXing. Wszystko działa jak należy, jednakże potrzebuje dodać funkcję rozpoznawania kodów. W tym celu doszedlem do "linq to xml" gdyż pamięć izolowana i localdb w WP 8.1 wydała mi się zbyt skomplikowana.

void cam_CaptureImageAvailable(object sender, ContentReadyEventArgs e)
        {
 
            Dispatcher.BeginInvoke(() =>
            {
 
                //skanowanie
                //outputImg.Source = img;
 
                BitmapImage img = new BitmapImage();
                img.SetSource(e.ImageStream);
                WriteableBitmap barcodeBitmap = new WriteableBitmap(img);
                // create a barcode reader instance
                IBarcodeReader reader = new BarcodeReader();
                // detect and decode the barcode inside the bitmap
                var result = reader.Decode(barcodeBitmap);
 
      XElement xelement = XElement.Load("produkty.xml");
                //IEnumerable<XElement> produkty = xelement.Elements();
                var prod = from p in xelement.Descendants("PRODUKT")
                           where p.Element("ID").Value == result.Text
                           select p.Element("NAZWA").Value;
                foreach (var p in prod)
 
        if (result != null)
                     {
                         MessageBox.Show(string.Format("Format: {0} {1} Content: {2} {3} Product: {4}", result.BarcodeFormat.ToString(),                System.Environment.NewLine, result.Text, System.Environment.NewLine, p ));
                      }
                timer.Change(1000, 1000);
 
            });
        } 

W tym momencie powyższy kod nie wywala błędów ale także uniemożliwia pierwotne działanie aplikacji.
Zauważyłem także ze wywala mi wyjątek (zamieszczam w załączniku).
Wydaje mi się, że to on uniemożliwia mi w tym momencie wyświetlanie tych produktów.

Dodaje także mojego xml'a, jest to prosty składniowo plik, wstępnie nie będzie zawierał dużo danych.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Edited by XMLSpy -->
<PRODUKTY>
     <PRODUKT>
        <ID>9788372292704</ID>
        <NAZWA>Ksiazka</NAZWA>
    </PRODUKT>
     <PRODUKT>
        <ID>13124123</ID>
    <NAZWA>Bob Dylan</NAZWA>
    </PRODUKT>
     <PRODUKT>
            <ID>2096000099067</ID>
        <NAZWA>Kod kreskowy</NAZWA>
    </PRODUKT>
</PRODUKTY>

Pozostało 580 znaków

2015-01-03 00:40
Krwawy Lew
0

Zakomentowałem ta linijke System.Diagnostics.Debugger.Break();

 private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            if (System.Diagnostics.Debugger.IsAttached)
            {
                // An unhandled exception has occurred; break into the debugger
               // System.Diagnostics.Debugger.Break();
            }
        }

i przy którymś break lub continue tego wyjątku wskazało mi na ten fragment

  where p.Element("ID").Value == result.Text

result.Text ponoć ma wartość null, ktoś wie dlaczego tak może sie dziać lub jak to wyeliminować?

Ewentualnie jakieś inne metody na wyciąganie nazwy produktu po kodzie kreskowym??

Pozostało 580 znaków

2015-01-03 10:30
1

Sprawdzaj, czy result.Text nie jest nullem i dopiero wtedy próbuj wyszukiwać.

Pozostało 580 znaków

2015-01-03 14:49
Krwawy Lew
0

Jeju to takie oczywiste, wprawdzie musialem zrobic 3 podejscie do Twojej odpowiedzi ale załapałem i chodzi. Dziękuje

Pozostało 580 znaków

2015-01-03 17:57
Krwawy Lew
0

Mam jeszcze 1 mały mankament. Mianowicie gdy umiescilem kod "linq to xml" w tym ifie by pozbyc sie wartosci null w zmiennej result.text

  if (result != null)
       {
            XElement xelement = XElement.Load("produkty.xml")
                var prod = from p in xelement.Descendants("PRODUKT")
                           where p.Element("ID").Value == result.Text
                           select p.Element("NAZWA").Value;
                foreach (var p in prod)
                            MessageBox.Show(string.Format("Format: {0} {1} Content: {2} {3} Product: {4}", result.BarcodeFormat.ToString(),                 System.Environment.NewLine, result.Text, System.Environment.NewLine, p ));
        }

to rozpozawany jest jedynie produkt zawarty w pliku xml. W innym wypadku aplikacja nie rozpoznaje kodu.
Kombinowalem na różne sposoby, m.in dodajac zmienna

var r = "nieznany produkt"; 

i tworzac cos takiego if (result != null)
{
XElement xelement = XElement.Load("produkty.xml");
var prod = from p in xelement.Descendants("PRODUKT")
where p.Element("ID").Value == result.Text
select p.Element("NAZWA").Value;
foreach (var p in prod)

                    if (p != null)
                    {
                        MessageBox.Show(string.Format("Format: {0} {1} Content: {2} {3} Product: {4}", result.BarcodeFormat.ToString(), System.Environment.NewLine, result.Text, System.Environment.NewLine, p));
                    }
                    else if (p == null)
                    {
                        MessageBox.Show(string.Format("Format: {0} {1} Content: {2} {3} Product: {4}", result.BarcodeFormat.ToString(), System.Environment.NewLine, result.Text, System.Environment.NewLine, r));
                    }

            }

Jednakże bez skutku. Domyślam sie iż if w ifie to blad (pewnie nawet karygodny) ale nie mam pojecia jak moglbym sprawdzac zmienna p, ktora zadeklarowana jest w tym pierwszym ifie.  Ktos moglby mnie naprowadzic?

Dodam iż nie moge brac pod uwage warunku 
```csharp
result ==  null

poniewaz najczesciej on bedzie wylapywany (chyba przez mankamenty biblioteki ZXing w C#, podobno kiepsko sie sprawdza)

Pozostało 580 znaków

2015-01-07 22:14
0

Odświeżam temat ponieważ próbowałem już na n sposobów i nie umiem sobie poradzić.
Zmieniłem trochę strukturę xml:

<?xml version="1.0" encoding="UTF-8"?>
<PRODUKTY>
  <PRODUKT Nazwa="Ksiazka">
    <ID>9788372292704</ID>
  </PRODUKT>
  <PRODUKT Nazwa="Bob Dylan">
    <ID>13124123</ID>
  </PRODUKT>
  <PRODUKT Nazwa="Kodzik">
    <ID>5907134821257</ID>
  </PRODUKT>
</PRODUKTY>

i wczytuje go trochę inaczej (wydaje mi sie ze lepiej)

void cam_CaptureImageAvailable(object sender, ContentReadyEventArgs e)
        {
            Dispatcher.BeginInvoke(() =>
            {
                BitmapImage img = new BitmapImage();
                img.SetSource(e.ImageStream);
                WriteableBitmap barcodeBitmap = new WriteableBitmap(img);
                // create a barcode reader instance
                IBarcodeReader reader = new BarcodeReader();
                // detect and decode the barcode inside the bitmap
                var result = reader.Decode(barcodeBitmap);
        var r = "nieznany produkt";
 
           if (result != null)
           {
               XElement xelement = XElement.Load("xml1.xml");
               IEnumerable<XElement> PRODUKTY =
                       from p in xelement.Elements("PRODUKT")
                       where (string)p.Element("ID").Value == result.Text
                       select p;
               foreach (XElement p in PRODUKTY)
 
                       if (p.Element("ID").IsEmpty == true)
                       {
                           MessageBox.Show(string.Format("Format: {0} {1} Content: {2} {3} Product: {4}", result.BarcodeFormat.ToString(), System.Environment.NewLine, result.Text, System.Environment.NewLine, r));
                       }
                       else 
                       {
                           MessageBox.Show(string.Format("Format: {0} {1} Content: {2} {3} Product: {4}", result.BarcodeFormat.ToString(), System.Environment.NewLine, result.Text, System.Environment.NewLine, p.Attribute("Nazwa").Value));
                       }
 
           } 

jednak za żadne skarby nie moge osiagnac tego warunku

  if (p.Element("ID").IsEmpty == true)
                       {
                           MessageBox.Show(string.Format("Format: {0} {1} Content: {2} {3} Product: {4}", result.BarcodeFormat.ToString(), System.Environment.NewLine, result.Text, System.Environment.NewLine, r));
                       }

Próbowałem także uzyć takiego

if (p.Element("ID").Value != result.Text) 

oraz wielu innych i nadal to samo.
Nie wiem co jest nie tak bo program działa jeśli zczytywany produkt mam w pliku xml. Za chwile go usunę do testu i już wtedy nie rozpoznaje ( nie inicjuje dekodowania jakby albo nie wiem).

Pomożcie

I czy da się w C# zmienną zadeklarowaną w pętli użyć dalej w kodzie? - ArionR 2015-01-07 22:17
Zadeklarowaną w pętli nie, bo jest to zmienna lokalna. - some_ONE 2015-01-07 22:19

Pozostało 580 znaków

2015-01-07 23:10
0

Albo ja jestem ślepy albo ten warunek nigdy nie zostanie spełniony:

if (p.Element("ID").IsEmpty == true)

a ten to już na pewno:

if (p.Element("ID").Value != result.Text) 

Yubby dibby dibby dibby dibby dibby dibby dum..
edytowany 1x, ostatnio: DibbyDum, 2015-01-07 23:11

Pozostało 580 znaków

2015-01-08 00:25
0

Ale jeśli mam to ograniczenie

 where (string)p.Element("ID").Value == result.Text

top.Element("ID")


nigdy nie będzie pusty? Myślałem ze jeśli sczytany kod jest o takim id jak w pliku to wtedy p jest, jeśli nie to jest puste.

Ktoś ma pomysł jak mógłby w takim razie brzmieć warunek, który odróżni mi kod z result od tych umieszczonych w pliku?

Pozostało 580 znaków

2015-01-08 10:16
0

Skoro mają być inne niż w result.Text to warunek powinien wyglądać następująco:

IEnumerable<XElement> PRODUKTY =
  from p in xelement.Elements("PRODUKT")
  let xId = p.Element("ID")
  where xId != null && xId.Value != result.Text
  select p;

no chyba że ja źle zrozumiałem co chcesz osiągnąć.


Yubby dibby dibby dibby dibby dibby dibby dum..
edytowany 1x, ostatnio: DibbyDum, 2015-01-08 10:16

Pozostało 580 znaków

2015-01-08 12:32
0

Ta biblioteka, która rozpoznaje mi kody wypluwa po prostu format kodu czyli np : EAN13, Content czyli własnie ten kod no i dodałem Product żeby tam wrzucać nazwę produktu (którego znam czyli mam w pliku xml)

Założenie mojej aplikacji to używanie tego Barcode Readera do skanowania produktów, dlatego jeśli skanuje produkt i wprowadziłem już go do bazy(xml) to wyciąga mi nazwę tegoż produktu, jeśli zeskanowany kod nie znajduje się w pliku to wypluwa "nieznany produkt".
W tym momencie nie rozumiem właśnie dlaczego jeśli produktu nie było w bazie to nie mogłem nic osiągnąć.
Zrobiłem break'a i screena w momencie sczytywania produktu którego nie ma w bazie, może Ty coś poradzisz bo mi za wiele nie pomaga. f66f77fe03.png
Result na nim jest jak widać, jednak biblioteka go odczytuje. Czy można w tym zapytaniu odpytywać xml o zmienne pasujace do result.Text i zmienna nie pasujące?
A potem dodać ten warunek

  if (p.Element("ID").IsEmpty == false)
{// kod wypluwajacy "nieznany produkt"}
 if (k.Element("ID").IsEmpty == false) 
{//kod wypluwający nazwę produktu}

Użyłem wcześniej własnie tego warunku

 if (p.Element("ID").IsEmpty == true) 

i tutaj wypluwa nieznany produkt a w else żeby wyciągało mi produkt dlatego, że chciałem właśnie coś takiego osiągnąć jak opisałem wyżej. Pewnie to kwestia zapytania linq to xml, którego niestety nie ogarniam już bardziej.

Edit: Już łapie, nie tworzy mi w ogóle zmiennej p jeśli nie ma danego kodu w pliku. To teraz mam pytanie jak wywołać mojego message boxa jeśli nie ma zmiennej, da się takie coś wykombinować?

edytowany 3x, ostatnio: ArionR, 2015-01-08 14:12

Pozostało 580 znaków

2015-01-08 14:11
1

Result na nim jest jak widać, jednak biblioteka go odczytuje. Czy można w tym zapytaniu odpytywać xml o zmienne pasujace do result.Text i zmienna nie pasujące?

Czyli po prostu chcesz wszystkie:

IEnumerable<XElement> PRODUKTY =
  from p in xelement.Elements("PRODUKT")
  select p;

A później tylko pętla:

foreach (XElement p in PRODUKTY)
{
    var xId = p.Element("ID");
    if (xId != null)
    {
        if (xId .IsEmpty)
        {
            // "nieznany produkt"
        }
        else if(xId .Value == result.Text)
        {
            // p.Attribute("Nazwa").Value;
        }
    }
    else
    {
        // A jak jest null to coś...
    }
}

Btw. popracuj nad nazywaniem zmiennych po podczas kopiuj wklej kodu z twojego postu już powoli zaczynałem się gubić. :D


Yubby dibby dibby dibby dibby dibby dibby dum..

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0