[英]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.