Xml没有使用sax解析String作为输入

我有一个字符串输入,我需要从中提取简单信息,这里是示例xml(来自mkyong):

   yong mook kim mkyong 100000   low yin fong fong fong 200000   

我如何在我的代码中解析它(我的类中有一个字段String name ):

 public String getNameFromXml(String xml) { try { SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser saxParser = factory.newSAXParser(); DefaultHandler handler = new DefaultHandler() { boolean firstName = false; public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equalsIgnoreCase("firstname")) { firstName = true; } } public void characters(char ch[], int start, int length) throws SAXException { if (firstName) { name = new String(ch, start, length); System.out.println("First name is : " + name); firstName = false; } } }; saxParser.parse(xml.toString(), handler); } catch (Exception e) { e.printStackTrace(); } return name; } 

我收到了java.io.FileNotFoundException ,我发现它正在尝试查找文件myprojectpath + the entireStringXML

我究竟做错了什么?

添加在 :

这是我的主要方法:

 public static void main(String[] args) { Text tst = new Text("  yong mook kim mkyong 100000   low yin fong fong fong 200000 "); NameFilter cc = new NameFilter(); String result = cc.getNameFromXml(tst); System.out.println(result); } 

你应该替换saxParser.parse(xml.toString(), handler); 有以下一个:

 saxParser.parse(new InputSource(new StringReader(xml)), handler); 

我将重点介绍另一个问题,一旦您正确读取文件,您可能会遇到这个问题。

方法

 public void characters(char ch[], int start, int length) 

不会总是给你完整的文字元素 。 您可以自由地一次为您提供文本元素(内容)’n’个字符。 从文档 :

SAX解析器可以在一个块中返回所有连续的字符数据,或者它们可以将它分成几个块

因此,您应该在每次调用此方法时构建文本元素字符串(例如,使用StringBuilder ),并且只有在调用相应的endElement()方法时才解释/存储该文本。

这可能不会影响你。 但它会在未来的某个时间出现 – 可能是你最不期望的时候。 我在从小型XML文档转移到大型XML文档时遇到过这种情况,缓冲区能够保存整个小文档,但不能保存较大的文档。

一个例子(伪代码):

  public void startElement() { builder.clear(); } public void characters(char ch[], int start, int length) { builder.append(new String(ch, start, length)); } public void endElement() { // no do something with the collated text builder.toString(); } 

Mybe这个帮助。 它使用的是javax.xml.parsers.DocumentBuilder,它比SAX更容易

 public Document getDomElement(String xml){ Document doc = null; DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { DocumentBuilder db = dbf.newDocumentBuilder(); InputSource is = new InputSource(); is.setCharacterStream(new StringReader(xml)); doc = db.parse(is); } catch (ParserConfigurationException e) { Log.e("Error: ", e.getMessage()); return null; } catch (SAXException e) { Log.e("Error: ", e.getMessage()); return null; } catch (IOException e) { Log.e("Error: ", e.getMessage()); return null; } // return DOM return doc; } 

您可以使用NodeList遍历文档,并按名称检查每个节点

使用String作为第一个参数调用parse。 根据文档 ,字符串被解释为文件的URI

如果要直接解析String ,则必须首先将其转换为InputStream ,以便与parse(InputSource is, DefaultHandler dh)一起使用parse(InputSource is, DefaultHandler dh)方法( docu ):

 // transform from string to inputstream ByteArrayInputStream in = new ByteArrayInputStream(xml.toString().getBytes()); InputSource is = new InputSource(); is.setByteStream(in); // start parsing saxParser.parse(xml.toString(), handler); 

好像你从这里拿了这个例子。 您需要将带有绝对路径而不是字符串的文件传递给方法SAXParser.parse() ; 仔细看看这个例子。 方法parse() 定义如下

 public void parse(File f, DefaultHandler dh) throws SAXException, IOException 

如果你想要解析一个字符串 。 还有另一种采用Inputstream方法。

 public void parse(InputStream is, DefaultHandler dh) throws SAXException, IOException 

然后,您需要将您的字符串转换为InputStream 。 这是怎么做的 。