【问题标题】:SAX Parser will not read and print one section of my xml FileSAX Parser 不会读取和打印我的 xml 文件的一部分
【发布时间】:2011-09-04 17:02:48
【问题描述】:

我真的需要有人帮助我试图让我的解析器读取并只显示 xml 文件的一部分,我可以从上到下读取两次但是当我尝试在我的 xml 处理程序中使用内部标签时每个部分都没有这样做,并且会发疯并显示其中的一点

这是我的解析器的代码

package heavytime
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.content.Intent;
import android.os.Bundle;
//import android.view.View;
//import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

public class Mainweather extends Seskanoreweatherpart2Activity {

weatherlist sitesList = null;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main2);

     LinearLayout layout = new LinearLayout(this);
     layout.setOrientation(1);
     layout.setBackgroundColor(0xFF000080);

     TextView value [];

    try {

        /** Handling XML */
        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser sp = spf.newSAXParser();
        XMLReader xr = sp.getXMLReader();

        /** Send URL to parse XML Tags */
        URL sourceUrl = new URL(
        "http://www.seskanore.com/currentoutput.xml");


        /** Create handler to handle XML Tags ( extends DefaultHandler ) */
        XMLhandler XMLhandler = new XMLhandler();
        xr.setContentHandler(XMLhandler);
        xr.parse(new InputSource(sourceUrl.openStream()));

        } catch (Exception e) {
        System.out.println("XML Pasing Excpetion = " + e);
        }

        /** Get result from XMLhandler SitlesList Object */
        sitesList = XMLhandler.sitesList;

        /** Assign textview array lenght by arraylist size */
   //       item = new TextView[sitesList.getName().size()];
        value = new TextView[sitesList.getName().size()];

        /** Set the result text in textview and add it to layout */
        for (int i = 0; i < sitesList.getName().size(); i++) {
        value[i] = new TextView(this);
        value[i].setText(sitesList.getvalue().get(i)+ " is "           +sitesList.getitem().get(i));

        layout.addView(value[i]);

         }


        /** Set the layout view to display */
        setContentView(layout);
 }
 }

这是我的 XML 处理程序的代码

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

public class XMLhandler extends DefaultHandler {

Boolean currentElement = false;
Boolean temperature = false;
String currentValue = null;
//  int currentVal = 0;
public static weatherlist sitesList = null;

public static weatherlist getSitesList() {
return sitesList;
}

public static void setSitesList(weatherlist sitesList) {
XMLhandler.sitesList = sitesList;
}

 @Override
    public void startDocument() throws SAXException {
        // Some sort of setting up work
    } 

@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {

    currentElement = true;

if (localName.equals("weatherdata"))
{
    sitesList = new weatherlist();}
else if (localName.equals("item")){
        temperature = true;
        String attr = attributes.getValue("name");
        sitesList.setValue(attr);}


}



/** Called when tag closing*/
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {

currentElement = false;

/** set value*/ 
if (localName.equals("temperaturetags")){
    localName.equalsIgnoreCase("item");
    sitesList.setName(currentValue);
    localName.equalsIgnoreCase("value");
    sitesList.setitem(currentValue);

}


temperature = false;
}

/** Called to get tag characters*/
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {

if (currentElement) {
currentValue = new String(ch, start, length);
currentElement = false;
}
}

@Override
public void endDocument() throws SAXException {
    // Some sort of finishing up work
}   
}

这是用于显示解析信息的 Arraylist 的代码

    package heavytime
    import java.util.ArrayList;


    public class weatherlist {

private ArrayList<String> value = new ArrayList<String>();
private ArrayList<String> name = new ArrayList<String>();
private ArrayList<String> item = new ArrayList<String>();

/** In Setter method default it will return arraylist
* change that to add */

public ArrayList<String> getvalue() {
return value;
}

public void setValue(String value) {
this.value.add(value);
}

public ArrayList<String> getName() {
return name;
}

public void setName(String name) {
this.name.add(name);
}

public ArrayList<String> getitem() {
return item;
}

public void setitem(String item) {
this.item.add(item);
}

  }

我希望它只显示温度标签中的标签,但我尝试了所有方法,但似乎没有任何效果 有人可以帮我吗

非常感谢

【问题讨论】:

  • 你能粘贴 XML 吗?
  • xml 很长,在链接中解析来自

标签: android xml xml-parsing saxparser linkparser


【解决方案1】:

您犯了一个常见错误,即假设 characters 方法只会在解析器的一对 startElementendElement 调用之间调用一次,并在开始和结束标记之间提供 entore 内容。其实可以多次调用,每次调用只包含部分内容。

正确的处理方式是在 startElement 方法中创建或附加某种类型的累加器(通常是StringBuilderStringBuffer),在字符方法中累加到其中,然后在endElement 方法。

我认为您的代码中还有很多错误,但这可能是让它正常工作的开始。

为了只处理特定标签中的项目,您需要设置一个布尔标志,表示您在看到该标签时已在 startElement 方法中找到它,在 endElement 中将其设置为 false标签,并在从任何其他标签收集数据之前测试该标志。您需要对每个带有&lt;item&gt; 的子标签使用上述过程,因为它们包含作为字符的数据。

为了我自己的乐趣,并希望它可以帮助您更好地理解这一切,我编写了一个小处理程序,它将&lt;temperaturetags&gt; 下的数据收集到地图列表中。

package com.donroby;

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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class WeatherHandler extends DefaultHandler {

    private List<Map<String,String>> result = new ArrayList<Map<String,String>>();
    private Map<String,String> currentItem;
    private boolean collectingItems;
    private boolean collectingItem;
    private StringBuilder builder;

    public List<Map<String,String>> getResult() {
        return result;
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        if (qName.equals("temperaturetags")) {
            collectingItems = true;
        }
        else if (qName.equals("item") && collectingItems) {
            currentItem = new HashMap<String,String>();
            currentItem.put("name", attributes.getValue("name"));
            collectingItem = true;
        }
        else if (collectingItem) {
            builder = new StringBuilder();
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if (qName.equals("temperaturetags")) {
            collectingItems = false;
        }
        if (qName.equals("item") && collectingItems) {
            result.add(currentItem);
            currentItem = null;
            collectingItem = false;
        }
        else if (collectingItem) {
            currentItem.put(qName,  builder.toString());
            builder = null;
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        if (collectingItem &&(builder != null)) {
           builder.append(ch, start, length);
        }
    }
}

对于实际使用,我更有可能创建一个域对象并将其收集到该类的列表中,但这会使代码有点膨胀,超出了我想要做的快速示例。

【讨论】:

  • 我可以让解析器根据我在 XML 处理程序中使用的标签从上到下读取和打印整个 xml 表,这就是为什么我认为问题出在我搜索的方式上标签因为内部标签是相同的,唯一不同的标签是中间标签,所以如果我在 startelement 和 endelement 中放置一个字符串缓冲区,它将只允许我想要读取和显示的标签的一部分?跨度>
  • 啊,是的,我现在明白我哪里出错了 :) 谢谢你的帮助,非常感谢 :)
【解决方案2】:

characters()函数中,使用String.trim(),然后在继续之前检查是否String.length()&gt;0

然后分别在startElement()endElement() 事件中使用stack 模型和push()pop() 数据

【讨论】:

    猜你喜欢
    • 2016-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-26
    • 2017-12-21
    • 1970-01-01
    • 2018-01-07
    • 2014-06-14
    相关资源
    最近更新 更多