Java 使用Sax解析器跳过xml中元素的最简单方法是什么?

Java 使用Sax解析器跳过xml中元素的最简单方法是什么?,java,android,sax,Java,Android,Sax,我一直在寻找这个问题的答案,但我在任何地方找到的所有SAX资源都比我希望的要少一点。我正在为一家餐厅编写一个android应用程序,它可以让客人通过一个应用程序访问很长的列表,而不是翻阅一本书。我的xml如下所示: <bar> <liquor> <type>American Rye</type> <distillery>Sazerac<distillery> <b

我一直在寻找这个问题的答案,但我在任何地方找到的所有SAX资源都比我希望的要少一点。我正在为一家餐厅编写一个android应用程序,它可以让客人通过一个应用程序访问很长的列表,而不是翻阅一本书。我的xml如下所示:

<bar>
    <liquor>
        <type>American Rye</type>
        <distillery>Sazerac<distillery>
        <bottling>18 Year</bottling>
        <place>Frankfort, KY</place>
        <proof>90</proof>
        <price>20<price>
    </liquor>

    <beer>
        <type>American Microbrew</type>
        <brewery>New Belgium</brewery>
        <bottling>La Folie Sour Brown 750ml</bottling>
        <place>Fort Collins, CO</place>
        <price>20</price>
    </beer>
</bar>

美国黑麦
萨泽拉克
18年
肯塔基州法兰克福
90
20
美国微珠
新比利时
La Folie酸棕750ml
科林斯堡公司
20
当我只喝了几百瓶酒的时候,它的效果很好。然而,由于我使用了某些元素名称,例如“type”和“price”两次,这就把事情搞砸了。这是我的解析器:

public class BeerParser extends DefaultHandler {

private ArrayList<Beer> BeerL;
private boolean pastTheLiquor = false;

public ArrayList<Beer> getItems(String ArrayType){
    ArrayList<Beer> tmpItem = new ArrayList<Beer>();
    for (Beer beer : BeerL){
        if (beer.getType().equals(ArrayType)){
        tmpItem.add(beer);
            }
        }
    return tmpItem;
}


InputStream barXmlInputStream;

String tmpValue;


Beer beerTmp;



public BeerParser(InputStream barXmlInputStream) {



    this.barXmlInputStream = barXmlInputStream;

    BeerL = new ArrayList<Beer>();

    parseDocument();

    printDatas();

}

private void parseDocument() {



    SAXParserFactory factory = SAXParserFactory.newInstance();

    try {

        SAXParser parser = factory.newSAXParser();

        parser.parse(barXmlInputStream, this);



    } catch (ParserConfigurationException e) {

        System.out.println("ParserConfig error");

    } catch (SAXException e) {

        System.out.println("SAXException : xml not well formed");

    } catch (IOException e) {

        System.out.println("IO error");

    }

}

private void printDatas() {


    for (Beer tmpB : BeerL) {

        System.out.println(tmpB.toString());

    }


}

@Override

public void startElement(String s, String s1, String elementName, Attributes attributes) throws SAXException {


    if (elementName.equalsIgnoreCase("beer")) {

        pastTheLiquor = true;
        beerTmp = new Beer();



    }

}

@Override

public void endElement(String s, String s1, String element) throws SAXException {


    if (element.equals("beer")) {

            BeerL.add(beerTmp);

        }
    if (pastTheLiquor){
        if (element.equalsIgnoreCase("type")) {

            beerTmp.setType(tmpValue);

        }
        if (element.equalsIgnoreCase("brewery")) {

            beerTmp.setBrewery(tmpValue);

        }
        if (element.equalsIgnoreCase("bottling")) {

            beerTmp.setBottling(tmpValue);
            beerTmp.hasBottling = true;

        }

        if (element.equalsIgnoreCase("price")) {

            beerTmp.setPrice(tmpValue);

        }

        if (element.equalsIgnoreCase("place")) {

            beerTmp.setPlace(tmpValue);

        }
    }

}



@Override

public void characters(char[] ac, int i, int j) throws SAXException {

    tmpValue = new String(ac, i, j);

}
公共类BeerParser扩展了DefaultHandler{
私人ArrayList BeerL;
私有布尔PastTheLikor=false;
公共ArrayList getItems(字符串ArrayType){
ArrayList tmpItem=新的ArrayList();
啤酒(啤酒:啤酒){
if(beer.getType().equals(ArrayType)){
t添加(啤酒);
}
}
返回tmpItem;
}
InputStream barXmlInputStream;
字符串tmpValue;
啤酒;
公共BeerParser(InputStream barXmlInputStream){
this.barXmlInputStream=barXmlInputStream;
BeerL=newarraylist();
解析文档();
printDatas();
}
私有文档(){
SAXParserFactory=SAXParserFactory.newInstance();
试一试{
SAXParser parser=factory.newSAXParser();
parse(barXmlInputStream,this);
}捕获(ParserConfiguration异常e){
System.out.println(“ParserConfig错误”);
}捕获(SAXE异常){
System.out.println(“SAXException:xml格式不正确”);
}捕获(IOE异常){
System.out.println(“IO错误”);
}
}
私有void printDatas(){
啤酒(tmpB:BeerL){
System.out.println(tmpB.toString());
}
}
@凌驾
public void startElement(字符串s、字符串s1、字符串elementName、属性)引发SAXException{
if(elementName.equalsIgnoreCase(“啤酒”)){
PastTheLikor=真;
beerTmp=新啤酒();
}
}
@凌驾
公共void endElement(字符串s、字符串s1、字符串元素)引发SAXException{
if(元素等于(“啤酒”)){
BeerL.add(beerTmp);
}
如果(通过液体){
if(element.equalsIgnoreCase(“类型”)){
beerTmp.setType(tmpValue);
}
if(元素等信号案例(“啤酒厂”)){
beerTmp.setBrewery(tmpValue);
}
if(元素等信号(“装瓶”)){
beerTmp.setbotting(TMP值);
beerTmp.hasbotting=true;
}
if(要素等信号情况(“价格”)){
beerTmp.setPrice(tmpValue);
}
if(元素等信号情况(“地点”)){
beerTmp.设置位置(TMP值);
}
}
}
@凌驾
公共无效字符(char[]ac,int i,int j)引发异常{
tmpValue=新字符串(ac,i,j);
}
}

因此,酒在啤酒之前出现,因此,因为解析器在看到“啤酒”之前看到了“类型”,所以它试图调用啤酒对象beerTmp的“setType()”函数,而beerTmp从未实例化过。我尝试使用一个布尔值,它会一直等到解析器看到第一个“beer”实例,但是我得到了一个空列表,这真的让我很沮丧,因为几乎相同的解析器生成了一个liquirs数组,它工作得非常出色


有没有一种简单的方法可以跳过文件中的酒?我的布尔值正确吗?我应该将SAX解析器抛出窗口并使用其他东西吗?多谢各位

> P> SAX解析器调用所有元素的回调,如果不想考虑其中的一些元素,只需快速执行“返回”即可。在解析之前没有办法过滤掉它们

有没有一种简单的方法可以跳过文件中的酒?我的布尔值正确吗

您可以使用结构来保存稍后需要考虑的数据(推送)。
SAX肯定比其他XML API更难驯服,因为在某些情况下,它是唯一的选择。所以,不要放弃它;在这之前或之后,你都会需要它。

以下是简化的病毒工程。注意

1) 您的xml有漏洞,例如
American Rye

2) equalsIgnoreCase不相关,因为xml区分大小写

3) JAXB最适合这项工作

public class BeerParser extends DefaultHandler {
    private List<Beer> list = new ArrayList<>();
    private Beer beer;
    private String element;

    public static void main(String[] args) throws Exception {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser = factory.newSAXParser();
        BeerParser bp = new BeerParser();
        parser.parse(new File("1.xml"), bp);
        System.out.println(bp.list);
    }

    @Override
    public void startElement(String s, String s1, String element, Attributes attributes) {
        if (element.equals("beer")) {
            beer = new Beer();
        }
        this.element = element;
    }

    @Override
    public void endElement(String s, String s1, String element) {
        if (element.equals("beer")) {
            list.add(beer);
            beer = null;
        }
    }

    @Override
    public void characters(char[] ac, int i, int j) {
        if (beer != null) {
            String value = new String(ac, i, j);
            if (element.equals("type")) {
                beer.setType(value);
            } else if (element.equals("brewery")) {
                beer.setBrewery(value);
            } else if (element.equals("bottling")) {
                beer.setBottling(value);
            } else if (element.equals("price")) {
                beer.setPrice(value);
            } else if (element.equals("place")) {
                beer.setPlace(value);
            }
        }
    }
}
公共类BeerParser扩展了DefaultHandler{
私有列表=新的ArrayList();
私人啤酒;
私有字符串元素;
公共静态void main(字符串[]args)引发异常{
SAXParserFactory=SAXParserFactory.newInstance();
SAXParser parser=factory.newSAXParser();
BeerParser bp=新的BeerParser();
parser.parse(新文件(“1.xml”),bp);
系统输出打印项次(bp列表);
}
@凌驾
public void startElement(字符串s、字符串s1、字符串元素、属性){
if(元素等于(“啤酒”)){
啤酒=新啤酒();
}
this.element=元素;
}
@凌驾
公共void元素(字符串s、字符串s1、字符串元素){
if(元素等于(“啤酒”)){
添加(啤酒);
啤酒=零;
}
}
@凌驾
公共无效字符(字符[]ac,整数i,整数j){
if(啤酒!=null){
字符串值=新字符串(ac,i,j);
if(element.equals(“type”)){
啤酒。设定类型(值);
}else如果(元素等于(“啤酒厂”)){
啤酒,啤酒(价值);
}else if(元素等于(“装瓶”)){
啤酒。啤酒瓶(价值);
}如果(要素等于(“价格”)){
啤酒。设定价格(价值);
}else if(元素等于(“位置”)){
啤酒