2013-06-17 10 views
5

Muszę opracować aplikację na Androida.Uzyskaj listę wartości używając parsera dom w Androidzie

Poniżej przedstawiam następujący format xml.

<Product> 
<product name="viki" productid="111"> 
<ProductType> 
<producttype>Nokia</producttype> 
<producttype>Samsung</producttype> 
</ProductType> 
</product> 
</Product> 

Tutaj muszę uzyskać Producttype dla particluar product.so mam napisał następujący kod:

if(subCategoryChildNode.hasChildNodes()){ 
      // parse 'Subcategory' childs 
     NodeList productNL = subCategoryChildElmt.getElementsByTagName("product"); 
     if(productNL.getLength() > 0){ 

     ArrayList<Product> productAL = new ArrayList<Product>(); 
     Product productBean = null; 
     for(int pCnt=0;pCnt<productNL.getLength();pCnt++){ 
      Node productNode = productNL.item(pCnt); 

      Element productElmt = null; 
      // parse 'product' tag attributes 
      if(productNode.hasAttributes()){ 
       productBean = new Product(); 
       productElmt = (Element)productNode; 
       productBean.setmProductName(productElmt.getAttribute("name")); 
      } 
      if(productNode.hasChildNodes()){ 
       NodeList productTypeNL = productElmt.getElementsByTagName("ProductType"); 
       if(productTypeNL.getLength() > 0){ 
        ArrayList<ProductType> ProductTypeAL = new ArrayList<ProductType>(); 
        ProductType productTypeBean = null; 
        for(int ptCnt=0;ptCnt<productTypeNL.getLength();ptCnt++){ 
        Node productTypeNode = productTypeNL.item(ptCnt); 
        Element productTypeElmt = null; 
        if(productTypeNode.hasChildNodes()){ 
         productTypeBean = new ProductType(); 
         productTypeElmt = (Element)productTypeNode; 
         productTypeBean.setmProductType(XMLfunctions.getValue(productTypeElmt,"producttype")); 
         System.out.println("Product Types are "+ " "+XMLfunctions.getValue(productTypeElmt,"producttype")); 
         ProductTypeAL.add(productTypeBean); 
        } 
        productBean.setmProductTypes(ProductTypeAL); 
        } 
       productAL.add(productBean); 
       } 
      } 
      subCategoryBean.setmProducts(productAL); 
     } 
     } 
    subCategoryAL.add(subCategoryBean); 
} 

Tutaj otrzymuję wartość jest nokia alone.but muszę pokazywać wartość nokia , samsung ... jeśli muszę uruchomić aplikację oznacza uzyskanie pojedynczej wartości.Ale muszę uzyskać listę wszystkich wartości ..

Co jest nie tak w moim kodzie. Proszę sprawdzić i dać mi rozwiązanie fot? ?

+0

W dzienniku widzisz, że "Typy produktów to Nokia", a "Typy produktów to Samsung"? – MagicMicky

+0

Dlaczego nie używać parsera SAX, jest on wydajniejszy pod względem pamięci niż przechowywanie wszystkiego w pamięci w parserze DOM - a aplikacje na Androida mają ograniczoną pamięć. – NoBugs

+0

@NoBugs tak Próbowałem tego. Ale mam więcej problemów z robieniem parsera sax.That, dlaczego mam chossing parser DOM. – user2218667

Odpowiedz

6

Powodem dostajesz tylko jeden <producttype> (Nokia) zamiast pełnej listy, ponieważ jesteś zapętlenie nad długością <ProductType> węzłów myślenia jesteś zapętlenie nad <producttype> nich.

Tak, trzeba inną wewnętrzną pętlę na wszystkie węzły typu produktów jak dziecko

for(int ptCnt=0; ptCnt < productTypeNL.getLength(); ptCnt++) { 
    Node productTypeNode = productTypeNL.item(ptCnt); 
    if(productTypeNode.hasChildNodes()){ 
     NodeList childProductTypeNL = productTypeNode.getChildNodes(); 
     System.out.print("Product Types are: "); 
     for (int cptCnt=0; cptCnt < childProductTypeNL.getLength(); cptCnt++) { 
      productTypeBean = new ProductType(); 
      productTypeBean.setmProductType (
          childProductTypeNL.item(cptCnt).getTextContent()); 
      System.out.print(productTypeBean.getmProductType() + ", "); 
      ProductTypeAL.add(productTypeBean); 
     } 
    } 
    productBean.setmProductTypes(ProductTypeAL); 
} 

ja bezpośrednio stosowanych metod Node.getChildNodes() i Node.getTextContexnt() zamiast typu odlewania do Element pierwszym i używając swoich metod lub klasa narzędziowa XMLfunctions.

Polecam również używanie różnych nazw dla węzłów potomnych, zamiast polegać na użyciu innego przypadku, aby uniknąć takich problemów w przyszłości. Prostym sposobem na uniknięcie kolizji nazw (gdy nie możesz wymyślić innej nazwy) jest po prostu użycie liczby mnogiej takiej jak <ProductTypes> dla tagu nadrzędnego.

Jednak lepszym podejściem, gdy trzeba parsować głęboko w drzewie DOM, jest użycie XPath, aby bezpośrednio uzyskać listę węzłów, które są zainteresowane. Nie jestem do końca pewien, co robi program, ale po prostu daje przykład XPath jak

String xpath = "//product[@name=\"viki\"]/ProductType/producttype"; 

dałby ci NodeList dla <producttype> węzły bezpośrednio.

+0

Dzięki za dał mi tak wspaniałe rozwiązanie. Dziękuję bardzo. Dziękuję bardzo. Nauczyli się więcej z tych odpowiedzi. – user2218667

+0

@ user2218667 Cieszę się, że mogę Ci pomóc. Dzięki za uznanie. –

1

Powiedziałbym, że jednym z problemów z twojego kodu (może być inne), jest to, że deklarujesz swoje productTypeBean i productTypeElmt przed pętlą for, a ponieważ nie jest to wymagane później, nie jest potrzebne.

if(subCategoryChildNode.hasChildNodes()){ 
     // parse 'Subcategory' childs 
    NodeList productNL = subCategoryChildElmt.getElementsByTagName("product"); 
    if(productNL.getLength() > 0){ 
     ArrayList<Product> productAL = new ArrayList<Product>(); 
     Product productBean = null; 
     for(int pCnt=0;pCnt<productNL.getLength();pCnt++){ 
      Node productNode = productNL.item(pCnt); 

      Element productElmt = null; 
      // parse 'product' tag attributes 
      if(productNode.hasAttributes()){ 
       productBean = new Product(); 
       productElmt = (Element)productNode; 
       productBean.setmProductName(productElmt.getAttribute("name")); 
      } 
      if(productNode.hasChildNodes()){ 
       NodeList productTypeNL = productElmt.getElementsByTagName("ProductType"); 
       if(productTypeNL.getLength() > 0){ 
        ArrayList<ProductType> ProductTypeAL = new ArrayList<ProductType>(); 
        for(int ptCnt=0;ptCnt<productTypeNL.getLength();ptCnt++){ 
         Node productTypeNode = productTypeNL.item(ptCnt); 
         if(productTypeNode.hasChildNodes()){ 
          ProductType productTypeBean = new ProductType(); 
          Element productTypeElmt = (Element)productTypeNode; 
          productTypeBean.setmProductType(XMLfunctions.getValue(productTypeElmt,"producttype")); 
          System.out.println("Product Types are "+ " "+XMLfunctions.getValue(productTypeElmt,"producttype")); 
          ProductTypeAL.add(productTypeBean); 
         } 
         productBean.setmProductTypes(ProductTypeAL); 
        } 
        productAL.add(productBean); 
       } 
      } 
      subCategoryBean.setmProducts(productAL); 
     } 
    } 
    subCategoryAL.add(subCategoryBean); 
}