Có một luồng XML mà tôi cần phân tích cú pháp. Vì tôi chỉ cần làm điều đó một lần và xây dựng các đối tượng java của mình, SAX trông giống như sự lựa chọn tự nhiên. Tôi đang mở rộng DefaultHandler và thực hiện các phương thức startElement, endElement và ký tự, có các thành viên trong lớp của tôi, nơi tôi lưu giá trị đọc hiện tại (được lấy trong phương thức ký tự).Java SAX Parsing
Tôi không gặp khó khăn khi làm những gì tôi cần, nhưng mã của tôi khá phức tạp và tôi chắc chắn không có lý do gì và tôi có thể làm những việc khác nhau. Cấu trúc của XML của tôi là một cái gì đó như thế này:
<players>
<player>
<id></id>
<name></name>
<teams total="2">
<team>
<id></id>
<name></name>
<start-date>
<year>2009</year>
<month>9</month>
</start-date>
<is-current>true</is-current>
</team>
<team>
<id></id>
<name></name>
<start-date>
<year>2007</year>
<month>11</month>
</start-date>
<end-date>
<year>2009</year>
<month>7</month>
</end-date>
</team>
</teams>
</player>
</players>
Vấn đề của tôi bắt đầu khi tôi nhận ra rằng tên thẻ tương tự được sử dụng trong một số lĩnh vực của tập tin. Ví dụ: id và tên tồn tại cho cả người chơi và nhóm. Tôi muốn tạo ra các thể hiện của các lớp java của tôi Player và Team. Trong khi phân tích cú pháp, tôi giữ các cờ boolean cho tôi biết liệu tôi có ở trong phần nhóm để trong endElement tôi sẽ biết rằng tên đó là tên của một đội, không phải tên của người chơi và vân vân.
Sau đây là cách mã của tôi trông giống như:
public class MyParser extends DefaultHandler {
private String currentValue;
private boolean inTeamsSection = false;
private Player player;
private Team team;
private List<Team> teams;
public void characters(char[] ch, int start, int length) throws SAXException {
currentValue = new String(ch, start, length);
}
public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
if(name.equals("player")){
player = new Player();
}
if (name.equals("teams")) {
inTeamsSection = true;
teams = new ArrayList<Team>();
}
if (name.equals("team")){
team = new Team();
}
}
public void endElement(String uri, String localName, String name) throws SAXException {
if (name.equals("id")) {
if(inTeamsSection){
team.setId(currentValue);
}
else{
player.setId(currentValue);
}
}
if (name.equals("name")){
if(inTeamsSection){
team.setName(currentValue);
}
else{
player.setName(currentValue);
}
}
if (name.equals("team")){
teams.add(team);
}
if (name.equals("teams")){
player.setTeams(teams);
inTeamsSection = false;
}
}
}
Vì trong kịch bản thật của tôi Tôi có nhiều nút để một cầu thủ ngoài việc các đội bóng và các nút cũng có thẻ như tên và id, tôi thấy mình sai lầm với một số boolean tương tự như inTeamsSection và phương thức endElement của tôi trở nên dài và phức tạp với nhiều điều kiện.
Tôi nên làm gì khác? Làm thế nào tôi có thể biết những gì một thẻ tên, ví dụ, thuộc về?
Cảm ơn!
Tôi sẽ nói rằng việc sử dụng SAX là sự lựa chọn tự nhiên khoảng 7 năm trước. Hiện tại, lựa chọn tự nhiên là sử dụng JAXB (hoặc Xtream, hoặc XmlBeans hoặc JibX) – Tarlog
Đôi khi bạn chỉ phải thực hiện phân tích thủ công. Khi bạn đối phó với megabyte XML chuyển đổi nó thành các đối tượng Java không phải là một ý tưởng rất tốt. –
@ ʘleg - Nếu bạn sử dụng JAXB đối với các đối tượng không đối xứng từ một XMLStreamReader của StAX, bạn có thể xem các phần con của một tài liệu lớn hơn để quản lý các ràng buộc bộ nhớ. –