以下程序正确解析xml文件并将其名称元素值和rel的链接属性值展开。 我想将这两个值存储在ArrayList< UserDetail>
中UserDetail类:
public class UserDetail {
private String name;
private String mailid;
public String getMailid() {
return mailid;
}
public void setMailid(String mailid) {
this.mailid = mailid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
SAX解析类:
import java.util.ArrayList;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class ReadXMLFile {
public static void main(String argv[]) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
DefaultHandler handler = new DefaultHandler() {
boolean name = false;
boolean link = false;
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
//System.out.println("Start Element :" + qName);
if (qName.equalsIgnoreCase("fullName")) {
name = true;
}
if (qName.equalsIgnoreCase("link")) {
System.out.println("\t" + attributes.getValue("rel"));
}
}
public void endElement(String uri, String localName,
String qName, Attributes attributes) throws SAXException {
if (qName.equalsIgnoreCase("fullName")) {
name = false;
}
if (qName.equalsIgnoreCase("link")) {
link = false;
}
}
public void characters(char ch[], int start, int length) throws SAXException {
if (name) {
System.out.println("First Name : " + new String(ch, start, length));
name = false;
}
}
};
saxParser.parse("D://abc.xml", handler);
} catch (Exception e) {
e.printStackTrace();
}
}
}
XML文档:
<feed>
<entry>
<fullName>Manish Sahu</fullName>
<link rel='abc'/>
<link rel='self'/>
<link rel='edit'/>
</entry>
</feed>
答案 0 :(得分:1)
保持对正在构建的当前User对象的引用。
对于元素“entry”在startElement处实例化一个新的UserDetails,并将其存储在endElement的列表中(如果需要,可以在此处添加验证)。然后将当前用户设置为null以避免意外修改(例如,条目之外的链接元素)。
对于元素“link”,将“ref”属性的值添加到用户详细信息中(在UserDetails中应该有addLink方法或类似方法,而不是标量setter)。
对于元素“fullName”,将字符数据连接到StringBuilder(因为字符可能被调用多次,具体取决于解析器实现),并在endElement设置“当前用户”的名称,然后清除SB。
public static void main(String argv[]) {
//must be final since it is referenced from an anonymous class
final List<UserDetail> users = new ArrayList <UserDetail>();
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
DefaultHandler handler = new DefaultHandler() {
String element;
StringBuilder sb=new StringBuilder();
UserDetails user=null;
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
this.element=qName;
//create a new user
if (element.equals("entry")) user = new UserDetails();
//save attribute <link rel="...">
if (element.equals("link")&&user!=null)
user.addLink(attributes.getValue("rel"));
}
public void endElement(String uri, String localName,
String qName, Attributes attributes) throws SAXException {
if (element.equals("fullName")) {
//store the name given in character data
user.setName(sb.toString());
sb.setLength(0);
} else if (element.equals("entry")) {
users.add(user); //store the current user
user=null;
}
}
public void characters(char ch[], int start, int length) throws SAXException {
if (element.equals("fullName")) sb.append(ch, start, length);
}
};
saxParser.parse("D://abc.xml", handler);
//do something with the users
for (UserDetails user;users) System.out.println(user.getName()+" "+user.getMailid());
} catch (Exception e) {
e.printStackTrace();
//catching Exception is not a good practice!
}
}
我没有编译上面的代码,但是它类似于我在解析XML时所做的事情。在处理更复杂的内容模型时,保存qName而不是设置标志会有所帮助。 (在某些情况下,我用来保存一个堆栈,在startElement上推送元素名称并在endElement上弹出它。)