簡體   English   中英

Xml沒有使用sax解析String作為輸入

[英]Xml not parsing String as input with 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

我究竟做錯了什么?

添加在 :

這是我的主要方法:

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

你應該替換saxParser.parse(xml.toString(), handler); 以下是:

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

我將重點介紹另一個問題,一旦您正確讀取文件,您可能會遇到這個問題。

方法

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

不會總是給你完整的文字元素 您可以自由地一次為您提供文本元素(內容)'n'字符。 來自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();
   }

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遍歷文檔,並按名稱檢查每個節點

好像你從這里拿了這個例子。 您需要將帶有絕對路徑而不是字符串的文件傳遞給方法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 這是怎么做的

您使用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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM