解析android中的复杂xml

时间:2011-10-25 08:39:38

标签: android

我有一个aaplicaiton,其中我使用sax解析器解析此xml

http://feed.dinmat.no/android_proxy.php?action=find&find=&path=Svin&amount=15&page=1

我想解析这个xml中的所有葡萄酒标签来自特定的食谱

请给我一些想法

package dinmat.android.parser;

import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

import android.content.Context;
import android.util.Log;
import dinmat.android.R;
import dinmat.android.global.Global;
import dinmat.android.objects.Recipes_Wines;

public class XmlParser extends DefaultHandler
{

    public String RootElement;
    public String RecordElement;
    public String xmlURL;
    public Object mainObj;  
    public Object newObj;
    public boolean inProcess;

    public ArrayList<Object> Records = null;

    private final String TAG = "XmlParser";

    StringBuffer buffer = new StringBuffer(); 
    String elementName;
    String elementValue;
    String im;
    Context context;
    String NodeIDGEt;
    public XmlParser(String strURL,Object tempObj)
    {
//      xmlURL = strURL;
        Log.i("In SAXParser activity", " in XmlParser: *** ");
        mainObj = tempObj;      
        inProcess = false;
        xmlURL = strURL;

    }
    /*public XmlParser(InputStream open, Recipes tempObj) 
    {
        xmlURL = open.toString();
        mainObj = tempObj;      
        inProcess = false;
    }*/
    public ArrayList<Object> ParseFile(String rootElement ,String recordElement)
    {
        Log.i("In SAXParser activity", " in ParseFile: *** ");
        RootElement = rootElement;
        RecordElement = recordElement;      
        try
        {
            SAXParserFactory spf = SAXParserFactory.newInstance();
            SAXParser sp = spf.newSAXParser();
            XMLReader reader = sp.getXMLReader();
            reader.setContentHandler(this);
            Log.d(TAG," xmlURL ::: "+im );
            reader.parse(new InputSource(getClass().getResourceAsStream(xmlURL)));
//          reader.parse(xmlURL);
//          reader.parse(new InputSource(getClass().getResourceAsStream(xmlURL)));
//      reader.parse(new InputSource(im));
        }
        catch(Exception e)
        {
            e.printStackTrace();
            return null;
        }
        return this.Records;
    }

    public ArrayList<Object> parseUrl(String rootElement ,String recordElement)
    {
        RootElement = rootElement;
        RecordElement = recordElement;      
        try{
            URL sourceUrl = new URL(xmlURL);
            SAXParserFactory spf = SAXParserFactory.newInstance();
            SAXParser sp = spf.newSAXParser();
            XMLReader reader = sp.getXMLReader();
            reader.setContentHandler(this);

            reader.parse(new InputSource(sourceUrl.openStream()));
        }catch(Exception e){
            e.printStackTrace();
            return null;
        }
        return this.Records;
    }

    @Override
    public void startElement(String Uri, String localName,String qName,Attributes attributes) throws SAXException
    {
        //Log.i("In SAXParser activity", " in startElement: *** "+localName);
        elementValue = "";
        if(localName.length() > 0)
        {
            if(localName.equalsIgnoreCase(RootElement))
            {
                Records = new ArrayList<Object>();
            }
            else if(localName.equalsIgnoreCase(RecordElement))
            {
                newObj = ClassUtils.newObject(mainObj);

                ClassUtils.objectMapping(newObj, localName, elementValue);

                inProcess = true;
            }
            else if(localName.equalsIgnoreCase("wines"))
            {
                Log.e("In SAXParser activity", " in startElement wines: *** ");
                XmlParser xmlObjBars = new XmlParser("http://feed.dinmat.no/android_proxy.php?action=find&find=&path=Svin&amount=15&page=1", new Recipes_Wines());//getAssets().open("recipes.xml").toString(), new Recipes());
                if(xmlObjBars != null)
                {
                    Global.ayyRecipesWines = xmlObjBars.parseUrl("wines", "wine");
                }
                String LocationattsValue = attributes.getValue("id");
                //Log.e("In SAXParser activity", " startElement wineselementValue :: *** "+ LocationattsValue);
                //  ArrayList   Global.AttributeValues.add(LocationattsValue);
            }
            else if(localName.equalsIgnoreCase("wine"))
            {
                String LocationattsValue = attributes.getValue("id");
                Global.nodeID.add(NodeIDGEt);
                Global.WineId.add(LocationattsValue);
            }   

        }
    }

    @Override
    public void characters(char[] ch,int start,int length) throws SAXException{
        elementValue+= new String(ch,start,length).trim();      
        System.out.println("Element value is "+elementValue);
    }

    @Override
    public void endElement(String Uri,String localName,String qName) throws SAXException
    {
        Log.i("In SAXParser activity", " in endElement: *** "+localName);
        if(localName.equalsIgnoreCase(RecordElement)){
            Records.add(newObj);
            inProcess = false;
        }

        else if(localName.equalsIgnoreCase("wines"))
        {
            Log.e("In SAXParser activity", " in wines: *** "+elementValue+"mainObj.getClass()"+mainObj.getClass());
            /*ClassUtils.objectMapping(newObj, localName, elementValue);
            Log.e("In SAXParser activity", " in image- url: *** "+elementValue+"mainObj.getClass()"+mainObj.getClass());
            System.out.println("ClassNAme"+newObj.getClass().getName());
            System.out.println("ClassNAme"+mainObj.getClass().getName());
            if(newObj.getClass().getName().equals("com.bourbon.object.Bars"))
            {
            Global.barsImage.add(elementValue);
            System.out.println("Values"+elementValue);
            }
            if(newObj.getClass().getName().equals("com.bourbon.object.Bourbons"))
            {
            Global.bourbonsImage.add(elementValue);
            System.out.println("Values"+elementValue);
            }*/
        }


        else if(inProcess){     
            ClassUtils.objectMapping(newObj, localName, elementValue);          
        }

        if(localName.equalsIgnoreCase("node_id"))
        {
            //System.out.println("Node iD"+elementValue);
            NodeIDGEt=elementValue;

        }

    }   
}

2 个答案:

答案 0 :(得分:0)

我认为您可以使用xpath获取所有葡萄酒标签

Xpath表达式:

  • /食谱/食谱/葡萄酒/酒
  • //酒

第一个表达式比第二个表达式快,但wine节点必须始终在此路径中找到。 第二个表达式更慢(因为它评估所有节点),但它会找到所有葡萄酒,不管他们的路径。

http://developer.android.com/reference/javax/xml/xpath/package-summary.html

答案 1 :(得分:0)

在我看来,SAX解析器不是此任务的解决方案。 SAX解析器适用于非常简单的XML文件,但对于复杂的XML文件,代码变得更难以阅读。我建议使用XmlBeans - 假设你有一个可用的XSD文件。

但如果你开始使用SAX,这里有一些提示:

  1. onStartElement(recipe)inRecipe=true;
  2. onStartElement(node_id)if (inRecipe) { inNodeId=true; }
  3. onEndElement(node_id)if (inRecipe) { inNodeId=false; }
  4. onCharacters(String chars)if (inNodeId && (chars.equals("[desired recipe id]"))) { inDesiredRecipe=true; }
  5. onStartElement(wines)if (inDesiredRecipe) { inWines = true; }
  6. onStartElement(wine, String id)if(inWines) { wineList.add(id); }
  7. onEndElement(wines)inWines = false;
  8. onEndElement(recipe)inDesiredRecipe=false; inRecipe=false;
  9. 只是为了让您了解如何做到这一点 - 您可以提供所需食谱的ID,并获取与该食谱相关的所有葡萄酒的ID列表。但是你仍然需要得到关于葡萄酒的全部信息,这会使你的代码变得混乱,这就是为什么我不会使用SAX。