Ich brauche ein Programm, das eine XML-Datei verwendet, die den SAX-Parser in Java verwendet, um die .xml-Datei zu analysieren, in einer ArrayList zu speichern und Methoden aufzurufen um bestimmte Objekte mit der ArrayListe anzuzeigen.SAX-Parser - Umgang mit fehlerhaften Daten aus .XML-Datei
Mein Programm muss in der Lage sein, mit dem Benutzer umzugehen, der dem SAX-Parser schlechte Daten gibt, so dass, wenn er nicht nach einem bestimmten Tag sucht, er nicht bricht. Ich brauche es, um die Daten laden zu können und einen "check" -Befehl zu verwenden, um die Integrität der Daten zu überprüfen. Wenn dem Kunden beispielsweise kein Konto zugeordnet ist, gibt das Programm aus, welcher Kunde kein Konto hat.
Im Folgenden habe ich die Aufgabe für das Programm, den Handler und die .xml mit schlechten Daten unten aufgeführt.
Aufgabe für das Programm:
Prüfung: Mit diesem Befehl wird die Integrität der genannten Einträge zu überprüfen. Mit anderen Worten, es überprüft, ob alle Einträge eines bestimmten Typs korrekt sind. Wenn der Befehl beispielsweise lautet: Überprüfen Sie den Kunden , das Programm sollte alle Kunden (Vorname und Nachname) auflisten, die keine Konten haben. Verwandte Befehle sind: Konto überprüfen: jede Kontonummer ohne eine zugehörige Adresse auflisten Adresse überprüfen: eine beliebige Adresse ohne zugehöriges Messgerät auflisten Zähler prüfen: eine Zähler-ID ohne Zählerstände auflisten oder deren Messwerte nicht mit dem Zählertyp übereinstimmen, zB Push-Lesen von einem Polling-Meter.
.xml Datei:
<xml version="1.0" encoding="UTF-8">
<!-- Customer with no account -->
<customer lastName ="Anderson" firstName="Thomas">
</customer>
<!-- Account with no address -->
<customer lastName ="Baker" firstName="Susanne">
<account type="residential" accountNumber="999-999-99">
</account>
</customer>
<!-- Address with no meter -->
<customer lastName ="Charles" firstName="Henry">
<account type="residential" accountNumber="888-888-88">
<address type="apartment" unit="308" street="E 6th St." number="56" zipCode="13126"/>
</account>
</customer>
<!-- Meter with no readings -->
<customer lastName ="Davidson" firstName="Mary">
<account type="residential" accountNumber="666-666-66">
<address type="apartment" unit="308" street="W 9th St." number="67" zipCode="13126">
<meter id = "RM-4876-X4" brand="GE" type="poll" location = "West side of building"/>
</address>
</account>
</customer>
<!-- Meter with mismatched readings -->
<customer lastName ="Evans" firstName="Oscar">
<account type="residential" accountNumber="555-555-55">
<address type="house" street="E 10th St." number="78" zipCode="13126">
<meter id = "RM-4874-X4" brand="GE" type="poll" location = "North side">
<meterReading reading="650" date = "1413227815" flag="poll"/>
<meterReading reading="675" date = "1413314215" flag="push"/>
<meterReading reading="622" date = "1413400615" flag="poll"/>
</meter>
</address>
</account>
</customer>
</xml>
Handler File:
package csc241hw07;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class MyHandler extends DefaultHandler {
// Variables to hold current values
private ArrayList<Customer> customerList = new ArrayList<Customer>();
private Customer currentCustomer;
private Account currentAccount;
private Address currentAddress;
private Meter currentMeter;
//getter method for employee list
public ArrayList<Customer> getCustList() {
return customerList;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
if (qName.equalsIgnoreCase("customer")) {
//Create a customer object
String lastName = attributes.getValue("lastName");
String firstName = attributes.getValue("firstName");
currentCustomer = new Customer(lastName, firstName);
} else if (qName.equalsIgnoreCase("address")) {
// Create an Address object
String street = attributes.getValue("street");
int houseNumber = Integer.parseInt(attributes.getValue("number"));
String zipCode = attributes.getValue("zipCode");
String type = attributes.getValue("type");
String unit = attributes.getValue("unit");
if (type.equalsIgnoreCase("mailing")) {
// this is a mailing address -- assign to current customer
MailingAddress ma = new MailingAddress(street, houseNumber, zipCode, type);
currentCustomer.setMailingAddress(ma);
} else if (type.equalsIgnoreCase("house")) {
// Create a house
currentAddress = new House(street, houseNumber, zipCode, type);
} else if (type.equalsIgnoreCase("commercial")) {
// Create a commercial
currentAddress = new Commercial(street, houseNumber, zipCode, type);
} else if (unit != null) {
// Create an apartment
currentAddress = new Apartment(street, houseNumber, zipCode, type, unit);
} else {
System.out.println("Unknown address type:" + type);
}
if (currentAddress != null) {
// Assign this account to current address
currentAddress.setAccount(currentAccount);
currentAccount.addAddress(currentAddress);
}
} else if (qName.equalsIgnoreCase("meter")) {
// Create a meter object
String type = attributes.getValue("type");
String brand = attributes.getValue("brand");
String id = attributes.getValue("id");
if (type.equalsIgnoreCase("push")) {
currentMeter = new PushMeter(id, brand, type);
} else if (type.equalsIgnoreCase("poll")) {
currentMeter = new PollMeter(id, brand, type);
} else {
System.out.println("Unknown meter type: " + type);
}
if (currentMeter != null) {
// Set location
String location = attributes.getValue("location");
currentMeter.setLocation(currentAddress, location);
currentAddress.addMeter(currentMeter);
}
//System.out.println("METER:");
} else if (qName.equalsIgnoreCase("meterReading")) {
// Create a meter reading
//<meterReading reading="622" date = "1413400615" flag="push"/>
double reading = Double.parseDouble(attributes.getValue("reading"));
//System.out.println("DATE:");
ZoneOffset z = ZoneOffset.ofHours(5);
long epoch = Long.parseLong(attributes.getValue("date"));
LocalDateTime d = LocalDateTime.ofEpochSecond(epoch,0,z);
//System.out.println("DATE:" + d.toString());
String flag = attributes.getValue("flag");
MeterReading mr = new MeterReading(reading, d, flag, currentMeter);
// Add this to current meter
currentMeter.addReading(mr);
//System.out.println("METERREADING:");
} else if (qName.equalsIgnoreCase("account")) {
// <account type="residential" accountNumber="876-543-21">
String type = attributes.getValue("type");
String acctNum = attributes.getValue("accountNumber");
if (type.equalsIgnoreCase("residential")) {
// residential account
currentAccount = new ResidentialAccount(acctNum, currentCustomer);
} else if (type.equalsIgnoreCase("commercial")) {
currentAccount = new CommercialAccount(acctNum, currentCustomer);
} else {
System.out.println("Unknown account type:" + type);
}
if (currentAccount != null) {
// Add this account to current customer
currentCustomer.addAccount(currentAccount);
}
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qName.equalsIgnoreCase("customer")) {
customerList.add(currentCustomer);
currentCustomer = null;
} else if (qName.equalsIgnoreCase("meter")) {
currentMeter = null;
} else if (qName.equalsIgnoreCase("account")) {
currentAccount = null;
} else if (qName.equalsIgnoreCase("address")) {
currentAddress = null;
}
}
}
Thank you!
Haben Sie sich JaxB angesehen? Es behandelt elegant fehlende Tags. Es wird nicht mit fehlerhaften XML umgehen, aber ich glaube nicht, dass Sie das suchen. Keine Notwendigkeit, dies alles von Hand zu schreiben. –
Und was ist die Frage zu beantworten? – rpy
Die Frage, die ich stelle, lautet: Wenn der Parser nach einem bestimmten Tag sucht und es nicht finden kann, wie zeige ich dem Benutzer an, dass die von ihm verwendete .xml-Datei kein Tag enthält? – LJP1203