【问题标题】:Using SAXparser to get info to more than one element (Android)使用 SAXparser 获取多个元素的信息 (Android)
【发布时间】:2012-03-03 21:36:07
【问题描述】:

我是 Android 新手(也是 Java 新手),但现在我开始使用 Web 服务。

为了更好地理解如何解析 XML,我开始尝试这个教程:

http://www.anddev.org/novice-tutorials-f8/parsing-xml-from-the-net-using-the-saxparser-t353.html

使用本示例中使用的 XML:

<outertag>
<innertag sampleattribute="innertagAttribute">
<mytag>anddev.org rulez =)</mytag>
<tagwithnumber thenumber="1337"/>
</innertag>
</outertag>

我了解它是如何工作的(我猜),但是如果 XML 是这样的:

<outertag>
<innertag sampleattribute="innertagAttribute">
<mytag>anddev.org rulez =)</mytag>
<tagwithnumber thenumber="1337"/>
</innertag>
<innertag sampleattribute="innertagAttribute2">
<mytag>something</mytag>
<tagwithnumber thenumber="14214"/>
</innertag>
</outertag>

应用程序的类需要改变什么来获取各个元素的数据?

我很感激任何建议...

完整源代码:

  • ParseXML.java

    包org.anddev.android.parsingxml;

    导入 java.net.URL;

    导入 javax.xml.parsers.SAXParser; 导入 javax.xml.parsers.SAXParserFactory;

    导入 org.xml.sax.InputSource; 导入 org.xml.sax.XMLReader;

    导入android.app.Activity; 导入android.os.Bundle; 导入android.util.Log; 导入android.widget.TextView;

    公共类 ParsingXML 扩展 Activity {

    private final String MY_DEBUG_TAG = "WeatherForcaster";
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
    
        /* Create a new TextView to display the parsingresult later. */
        TextView tv = new TextView(this);
        try {
            /* Create a URL we want to load some xml-data from. */
            URL url = new URL("http://www.anddev.org/images/tut/basic/parsingxml/example.xml");
    
            /* Get a SAXParser from the SAXPArserFactory. */
            SAXParserFactory spf = SAXParserFactory.newInstance();
            SAXParser sp = spf.newSAXParser();
    
            /* Get the XMLReader of the SAXParser we created. */
            XMLReader xr = sp.getXMLReader();
            /* Create a new ContentHandler and apply it to the XML-Reader*/ 
            ExampleHandler myExampleHandler = new ExampleHandler();
            xr.setContentHandler(myExampleHandler);
    
            /* Parse the xml-data from our URL. */
            xr.parse(new InputSource(url.openStream()));
            /* Parsing has finished. */
    
            /* Our ExampleHandler now provides the parsed data to us. */
            ParsedExampleDataSet parsedExampleDataSet = 
                                    myExampleHandler.getParsedData();
    
            /* Set the result to be displayed in our GUI. */
            tv.setText(parsedExampleDataSet.toString());
    
        } catch (Exception e) {
            /* Display any Error to the GUI. */
            tv.setText("Error: " + e.getMessage());
            Log.e(MY_DEBUG_TAG, "WeatherQueryError", e);
        }
        /* Display the TextView. */
        this.setContentView(tv);
    }
    

    }

  • 示例处理程序

    包org.anddev.android.parsingxml;

    导入 org.xml.sax.Attributes; 导入 org.xml.sax.SAXException; 导入 org.xml.sax.helpers.DefaultHandler;

    公共类 ExampleHandler 扩展 DefaultHandler{

    // ===========================================================
    // Fields
    // ===========================================================
    
    private boolean in_outertag = false;
    private boolean in_innertag = false;
    private boolean in_mytag = false;
    
    private ParsedExampleDataSet myParsedExampleDataSet = new ParsedExampleDataSet();
    
    // ===========================================================
    // Getter & Setter
    // ===========================================================
    
    public ParsedExampleDataSet getParsedData() {
        return this.myParsedExampleDataSet;
    }
    
    // ===========================================================
    // Methods
    // ===========================================================
    @Override
    public void startDocument() throws SAXException {
        this.myParsedExampleDataSet = new ParsedExampleDataSet();
    }
    
    @Override
    public void endDocument() throws SAXException {
        // Nothing to do
    }
    
    /** Gets be called on opening tags like: 
     * <tag> 
     * Can provide attribute(s), when xml was like:
     * <tag attribute="attributeValue">*/
    @Override
    public void startElement(String namespaceURI, String localName,
            String qName, Attributes atts) throws SAXException {
        if (localName.equals("outertag")) {
            this.in_outertag = true;
        }else if (localName.equals("innertag")) {
            this.in_innertag = true;
        }else if (localName.equals("mytag")) {
            this.in_mytag = true;
        }else if (localName.equals("tagwithnumber")) {
            // Extract an Attribute
            String attrValue = atts.getValue("thenumber");
            int i = Integer.parseInt(attrValue);
            myParsedExampleDataSet.setExtractedInt(i);
        }
    }
    
    /** Gets be called on closing tags like: 
     * </tag> */
    @Override
    public void endElement(String namespaceURI, String localName, String qName)
            throws SAXException {
        if (localName.equals("outertag")) {
            this.in_outertag = false;
        }else if (localName.equals("innertag")) {
            this.in_innertag = false;
        }else if (localName.equals("mytag")) {
            this.in_mytag = false;
        }else if (localName.equals("tagwithnumber")) {
            // Nothing to do here
        }
    }
    
    /** Gets be called on the following structure: 
     * <tag>characters</tag> */
    @Override
    public void characters(char ch[], int start, int length) {
        if(this.in_mytag){
            myParsedExampleDataSet.setExtractedString(new String(ch, start, length));
        }
    }
    

    }

  • ParsedExampleDataSet

    包org.anddev.android.parsingxml;

    公共类 ParsedExampleDataSet { 私有字符串提取字符串 = null; private int extractInt = 0;

    public String getExtractedString() {
        return extractedString;
    }
    public void setExtractedString(String extractedString) {
        this.extractedString = extractedString;
    }
    
    public int getExtractedInt() {
        return extractedInt;
    }
    public void setExtractedInt(int extractedInt) {
        this.extractedInt = extractedInt;
    }
    
    public String toString(){
        return "ExtractedString = " + this.extractedString
                + "nExtractedInt = " + this.extractedInt;
    }
    

    }

【问题讨论】:

    标签: android saxparser


    【解决方案1】:

    问题解决了!

    以下是提供有用信息的网站:

    我最初的问题是如何为要从 XML 中提取的数据定义类。在我弄清楚我应该怎么做之后(回顾 JAVA 编程的基本概念),我将 ExampleHandler 返回的数据类型更改为 ArrayList。

    下面我举个例子:

    • 您要解析的 XML 示例:

      <outertag>
      <cartag type="Audi">
          <itemtag name="model">A4</itemtag>
          <itemtag name="color">Black</itemtag>
          <itemtag name="year">2005</itemtag>
      </cartag>
      <cartag type="Honda">
          <itemtag name="model">Civic</itemtag>
          <itemtag name="color">Red</itemtag>
          <itemtag name="year">2001</itemtag>
       </cartag>
       <cartag type="Seat">
          <itemtag name="model">Leon</itemtag>
          <itemtag name="color">White</itemtag>
          <itemtag name="year">2009</itemtag>
       </cartag>
       </outertag>
      

    所以在这里你应该定义一个具有适当属性(字符串类型、型号、颜色、年份;)、setter 和 getter 的类“car”...

    • 我对这个 XML 的 ExampleHandler 的建议是:

    公共类 ExampleHandler 扩展 DefaultHandler{

    // ===========================================================
    // Fields
    // ===========================================================
    
    private int numberOfItems=3;    
    private boolean in_outertag = false;
    private boolean in_cartag = false;
    private boolean[] in_itemtag = new boolean[numberOfItems];
    
    Car newCar = new Car(); 
    
    private ArrayList<Car> list = new ArrayList<Car>(); 
    
    // ===========================================================
    // Getter & Setter
    // ===========================================================
    
    public ArrayList<Car> getParsedData() {
        return this.list;
    }
    
    // ===========================================================
    // Methods
    // ===========================================================
    @Override
    public void startDocument() throws SAXException {
        this.list = new ArrayList<Car>();
    }
    
    @Override
    public void endDocument() throws SAXException {
        // Nothing to do
    }
    
    /** Gets be called on opening tags like: 
     * <tag> 
     * Can provide attribute(s), when xml was like:
     * <tag attribute="attributeValue">*/
    @Override
    public void startElement(String namespaceURI, String localName,
            String qName, Attributes atts) throws SAXException {
        if (localName.equals("outertag")) {
            this.in_outertag = true;
        }else if (localName.equals("cartag")) {
            this.in_cartag = true;
            newCar.setType(atts.getValue("type"));  //setType(...) is the setter defined in car class
        }else if (localName.equals("itemtag")) {
            if((atts.getValue("name")).equals("model")){
                this.in_itemtag[0] = true;
            }else if((atts.getValue("name")).equals("color")){
                this.in_itemtag[1] = true;
            }else if((atts.getValue("name")).equals("year")){
                this.in_itemtag[2] = true;
            }
        }
    }
    
    /** Gets be called on closing tags like: 
     * </tag> */
    @Override
    public void endElement(String namespaceURI, String localName, String qName)
            throws SAXException {
        if (localName.equals("outertag")) {
            this.in_outertag = false;
        }else if (localName.equals("cartag")) {
            this.in_cartag = false;
            Car carTemp = new Car();
            carTemp.copy(newCar, carTemp);  //this method is defined on car class, and is used to copy the
                                            //properties of the car to another Object car to be added to the list
            list.add(carTemp);
        }else if (localName.equals("itemtag")){
            if(in_itemtag[0]){
                this.in_itemtag[0] = false;
            }else if(in_itemtag[1]){
                this.in_itemtag[1] = false;
            }else if(in_itemtag[2]){
                this.in_itemtag[2] = false;
            }
        }
    }
    
    /** Gets be called on the following structure: 
     * <tag>characters</tag> */
    @Override
    public void characters(char ch[], int start, int length) {
    
        if(in_itemtag[0]){
            newCar.setModel(new String(ch, start, length));
        }else if(in_itemtag[1]){
            newCar.setColor(new String(ch, start, length));
        }else if(in_itemtag[2]){
            newCar.setYear(new String(ch, start, length));
        }
    }
    

    }

    在此之后,您可以使用以下方式在Activity中获取解析后的数据:

    ...
    ArrayList<Car> ParsedData = myExampleHandler.getParsedData();
    ...
    

    我希望这对某人有所帮助。

    注意:我没有完全这样测试过,但与我的解决方案几乎相同,所以它应该可以工作......

    对不起,我的英语不好......

    【讨论】:

    • 欢迎来到 Stack Overflow!您不应该只提供指向另一个站点的链接作为答案,因为该站点将来可能会过时。相反,请单击此答案上的“编辑”链接,并在此处包含该页面中解决方案的基本部分。见:meta.stackexchange.com/q/8259
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-05
    • 1970-01-01
    • 1970-01-01
    • 2011-11-25
    • 1970-01-01
    • 1970-01-01
    • 2013-07-30
    相关资源
    最近更新 更多