Xml not parsing String as input with sax

孤街浪徒 提交于 2019-12-04 18:29:40

问题


I have a string input from which I need to extract simple information, here is the sample xml (from 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>

How I parse it within my code (I have a field String name in my class) :

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

I'm getting a java.io.FileNotFoundException and I see that it's trying to find a file myprojectpath + the entireStringXML

What am I doing wrong?

Addon :

Here is my main method :

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

回答1:


You should replace the line saxParser.parse(xml.toString(), handler); with the following one:

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



回答2:


I'm going to highlight another issue, which you're likely to hit once you read your file correctly.

The method

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

won't always give you the complete text element. It's at liberty to give you the text element (content) 'n' characters at a time. From the doc:

SAX parsers may return all contiguous character data in a single chunk, or they may split it into several chunks

So you should build up your text element string from each call to this method (e.g. using a StringBuilder) and only interpret/store that text once the corresponding endElement() method is called.

This may not impact you now. But it'll arise at some time in the future - likely when you least expect it. I've encountered it when moving from small to large XML documents, where buffering has been able to hold the whole small document, but not the larger one.

An example (in pseudo-code):

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



回答3:


Mybe this help. it's uses javax.xml.parsers.DocumentBuilder, which is easier than 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;
    }

you can loop through the document by using NodeList and check each Node by it's name




回答4:


You call parse with a String as the first parameter. According to the docu that string is interpreted as the URI to your file.

If you want to parse your String directly, you have to transform it to an InputStream in the first place for usage with the parse(InputSource is, DefaultHandler dh) method (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);



回答5:


Seems you took this example from here . You need to pass a file with absolute path an not a string to method SAXParser.parse(); Look the example closely. The method parse() defined as follows

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

If you want to parse a string anyways. There is another method which takes Inputstream.

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

Then you need to convert your string to an InputStream. Here is how to do it.



来源:https://stackoverflow.com/questions/11192106/xml-not-parsing-string-as-input-with-sax

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!