使用 SAXparser 获取多个元素的信息 (Android)

发布于 2025-01-04 07:15:25 字数 5620 浏览 4 评论 0原文

我是 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 {

    私有最终字符串 MY_DEBUG_TAG = "WeatherForcaster";
    
    /** 首次创建活动时调用。 */
    @覆盖
    公共无效onCreate(捆绑冰柱){
        super.onCreate(冰柱);
    
        /* 创建一个新的TextView,用于稍后显示解析结果。 */
        TextView 电视 = new TextView(this);
        尝试 {
            /* 创建一个我们想要从中加载一些 xml 数据的 URL。 */
            URL url = 新 URL("http://www.anddev.org/images/tut/basic/parsingxml/example.xml");
    
            /* 从 SAXParserFactory 获取 SAXParser。 */
            SAXParserFactory spf = SAXParserFactory.newInstance();
            SAXParser sp = spf.newSAXParser();
    
            /* 获取我们创建的 SAXParser 的 XMLReader。 */
            XMLReader xr = sp.getXMLReader();
            /* 创建一个新的 ContentHandler 并将其应用到 XML-Reader*/ 
            ExampleHandler myExampleHandler = new ExampleHandler();
            xr.setContentHandler(myExampleHandler);
    
            /* 从我们的 URL 解析 xml 数据。 */
            xr.parse(new InputSource(url.openStream()));
            /* 解析完成。 */
    
            /* 我们的 ExampleHandler 现在向我们提供解析后的数据。 */
            解析示例数据集 解析示例数据集 = 
                                    myExampleHandler.getParsedData();
    
            /* 设置要在 GUI 中显示的结果。 */
            tv.setText(parsedExampleDataSet.toString());
    
        } catch (异常 e) {
            /* 将任何错误显示到 GUI。 */
            tv.setText("错误:" + e.getMessage());
            Log.e(MY_DEBUG_TAG, "WeatherQueryError", e);
        }
        /* 显示文本视图。 */
        this.setContentView(tv);
    }
    

    }

  • ExampleHandler

    包org.anddev.android.parsingxml;

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

    公共类ExampleHandler扩展了DefaultHandler{

    // ============================================ =================
    // 字段
    // ================================================== ===========
    
    私有布尔 in_outertag = false;
    私有布尔 in_innertag = false;
    私人布尔 in_mytag = false;
    
    私有 ParsedExampleDataSet myParsedExampleDataSet = new ParsedExampleDataSet();
    
    // ================================================== ===========
    // 吸气剂 &塞特
    // ================================================== ===========
    
    公共 ParsedExampleDataSet getParsedData() {
        返回 this.myParsedExampleDataSet;
    }
    
    // ================================================== ===========
    // 方法
    // ================================================== ===========
    @覆盖
    公共无效startDocument()抛出SAXException {
        this.myParsedExampleDataSet = new ParsedExampleDataSet();
    }
    
    @覆盖
    公共无效endDocument()抛出SAXException {
        // 没什么可做的
    }
    
    /** 在开始标签上被调用,例如: 
     * <标签> 
     * 可以提供属性,当 xml 类似于:
     * <标签属性=“attributeValue”>*/
    @覆盖
    公共无效startElement(字符串命名空间URI,字符串本地名称,
            字符串 qName,属性 atts) 抛出 SAXException {
        if (localName.equals("outertag")) {
            this.in_outertag = true;
        }否则 if (localName.equals("innertag")) {
            this.in_innertag = true;
        }否则 if (localName.equals("mytag")) {
            this.in_mytag = true;
        }else if (localName.equals("tagwithnumber")) {
            // 提取属性
            String attrValue = atts.getValue("thenumber");
            int i = Integer.parseInt(attrValue);
            myParsedExampleDataSet.setExtractedInt(i);
        }
    }
    
    /** 在结束标签上被调用,例如: 
     *  */
    @覆盖
    公共无效endElement(字符串命名空间URI,字符串本地名称,字符串qName)
            抛出 SAXException {
        if (localName.equals("outertag")) {
            this.in_outertag = false;
        }否则 if (localName.equals("innertag")) {
            this.in_innertag = false;
        }否则 if (localName.equals("mytag")) {
            this.in_mytag = false;
        }else if (localName.equals("tagwithnumber")) {
            // 这里没什么可做的
        }
    }
    
    /** 在以下结构上被调用: 
     * <标签>字符 */
    @覆盖
    公共无效字符(char ch[],int开始,int长度){
        如果(this.in_mytag){
            myParsedExampleDataSet.setExtractedString(new String(ch, start, length));
        }
    }
    

    }

  • ParsedExampleDataSet

    包org.anddev.android.parsingxml;

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

    public String getExtractedString() {
        返回提取的字符串;
    }
    公共无效setExtractedString(字符串提取字符串){
        this.extractedString = extractedString;
    }
    
    公共 int getExtractedInt() {
        返回提取的Int;
    }
    公共无效setExtractedInt(int extractedInt){
        this.extractedInt = extractedInt;
    }
    
    公共字符串 toString(){
        返回“ExtractedString =”+ this.extractedString
                + "nExtractedInt = " + this.extractedInt;
    }
    

    }

I'm new in Android (and in Java too) but now I'm starting to work with web services.

So to understand better how to parse an XML, I started to try this tutorial:

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

With the XML used in this example:

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

I understand how it works (I guess), but if the XML is like this:

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

What needs to change in the classes of the application to obtain the data of the various elements?

I appreciate any sugestion...

Full source code:

  • ParseXML.java

    package org.anddev.android.parsingxml;

    import java.net.URL;

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

    import org.xml.sax.InputSource;
    import org.xml.sax.XMLReader;

    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    import android.widget.TextView;

    public class ParsingXML extends 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);
    }
    

    }

  • ExampleHandler

    package org.anddev.android.parsingxml;

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

    public class ExampleHandler extends 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

    package org.anddev.android.parsingxml;

    public class ParsedExampleDataSet {
    private String extractedString = null;
    private int extractedInt = 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;
    }
    

    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

轻许诺言 2025-01-11 07:15:25

问题解决了!

以下是包含有用信息的网站:

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

我在下面给出了一个示例:

  • 您要解析的 XML 示例:

    ;
    
        A4
        黑色
        2005
    
    
        思域
        红色
        2001
     
     
        莱昂
        白色
        2009
     
     
    

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

  • 我的建议此 XML 的 ExampleHandler 的内容为:

public class ExampleHandler extends 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();
...

我希望这对某人有帮助。

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

并且为我糟糕的英语感到抱歉......

Problem solved!

Bellow are the sites with useful information:

My initial problem was how I should define the class for the data which I wanted to extract from XML. After I figured out how I should do this (reviewing the basic concepts of JAVA programming), I changed the type of data returned by the ExampleHandler to an ArrayList<"class of the data you want return">.

I give below an example:

  • Example of a XML you want to parse:

    <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>
    

So here you should define a class "car" with proper attributes (String type, model, color, year;), setters and getters...

  • My suggestion of ExampleHandler for this XML is:

public class ExampleHandler extends 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));
    }
}

}

After this, you can get the parsed data in the Activity using:

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

I hope this helps someone.

Attention: I don't have tested exactly like this, but is almost the same of my solution so it should work...

And sorry for my bad English...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文