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

时间:2012-06-25 15:16:29

标签: java xml sax

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

<?xml version="1.0"?>
<company>
    <staff>
        <firstname>yong</firstname>
        <lastname>mook kim</lastname>
        <nickname>mkyong</nickname>
        <salary>100000</salary>
    </staff>
    <staff>
        <firstname>low</firstname>
        <lastname>yin fong</lastname>
        <nickname>fong fong</nickname>
        <salary>200000</salary>
    </staff>
</company>

我如何在我的代码中解析它(我的班级中有一个字段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

我做错了什么?

Addon:

这是我的主要方法:

public static void main(String[] args) {
        Text tst = new Text("<?xml version=\"1.0\"?><company>   <staff>     <firstname>yong</firstname>     <lastname>mook kim</lastname>       <nickname>mkyong</nickname>     <salary>100000</salary> </staff>    <staff>     <firstname>low</firstname>      <lastname>yin fong</lastname>       <nickname>fong fong</nickname>      <salary>200000</salary> </staff></company>");
        NameFilter cc = new NameFilter();
        String result = cc.getNameFromXml(tst);
        System.out.println(result);
    }

5 个答案:

答案 0 :(得分:48)

您应该使用以下内容替换saxParser.parse(xml.toString(), handler);行:

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

答案 1 :(得分:2)

我要强调另一个问题,一旦你正确阅读文件,你可能会遇到这个问题。

方法

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

并不总能为您提供完整的文字元素。您可以自由地一次为您提供文本元素(内容)'n'字符。来自the doc

  

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();
   }

答案 2 :(得分:1)

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遍历文档,并按名称

检查每个节点

答案 3 :(得分:0)

似乎你从here获取了这个例子。您需要将带有绝对路径而不是字符串的文件传递给方法SAXParser.parse();仔细看一下这个例子。方法parse() defined as遵循

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

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

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

然后你需要将你的字符串转换为InputStream 。这是how to do it

答案 4 :(得分:0)

您使用String作为第一个参数调用解析。根据{{​​3}},该字符串被解释为您文件的URI

如果您想直接解析String,则必须首先将其转换为InputStream,以便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);