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