Tôi đã tìm kiếm các giải pháp cho vấn đề này quá lâu để xem xét nó dễ dàng như thế nào vì vậy tôi đã đến để được giúp đỡ.Xác nhận hợp lệ chống lại một Schema với JAXB
Tôi có một lược đồ XML mà tôi đã sử dụng với xjc để tạo liên kết JAXB của tôi. Điều này làm việc tốt khi XML được định dạng tốt. Thật không may, nó cũng không phàn nàn khi XML không được định dạng tốt. Tôi không thể tìm ra cách thực hiện xác nhận hợp lệ đầy đủ đối với lược đồ khi tôi cố gắng unmarshall một tệp XML.
Tôi đã quản lý để sử dụng ValidationEventCollector để xử lý sự kiện, hoạt động cho các lỗi phân tích cú pháp XML như thẻ không khớp nhưng không tăng bất kỳ sự kiện nào khi có thẻ bắt buộc nhưng hoàn toàn vắng mặt.
Từ những gì tôi đã thấy xác thực có thể được thực hiện chống lại lược đồ, nhưng bạn phải biết đường dẫn đến giản đồ để chuyển nó vào phương thức setSchema(). Vấn đề tôi có là đường dẫn đến lược đồ được lưu trữ trong tiêu đề XML và tôi không thể gõ vào thời gian chạy mà lược đồ sẽ có. Đó là lý do tại sao nó được lưu trữ trong file XML:
<?xml version="1.0" encoding="utf-8"?>
<DDSSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://stackoverflow.com/a/big/long/path/to/a/schema/file/DDSSettings.xsd">
<Field1>1</Field1>
<Field2>-1</Field2>
... vv
Mỗi ví dụ tôi thấy sử dụng setValidating (true), mà bây giờ bị phản đối, vì vậy ném một ngoại lệ.
Đây là mã Java tôi có cho đến nay, mà dường như chỉ làm xác nhận XML, không schema xác nhận:
try {
JAXBContext jc = new JAXBContext() {
private final JAXBContext jaxbContext = JAXBContext.newInstance("blah");
@Override
public Unmarshaller createUnmarshaller() throws JAXBException {
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
ValidationEventCollector vec = new ValidationEventCollector() {
@Override
public boolean handleEvent(ValidationEvent event) throws RuntimeException {
ValidationEventLocator vel = event.getLocator();
if (event.getSeverity() == event.ERROR || event.getSeverity() == event.FATAL_ERROR) {
String error = "XML Validation Exception: " + event.getMessage() + " at row: " + vel.getLineNumber() + " column: " + vel.getColumnNumber();
System.out.println(error);
}
m_unmarshallingOk = false;
return false;
}
};
unmarshaller.setEventHandler(vec);
return unmarshaller;
}
@Override
public Marshaller createMarshaller() throws JAXBException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
@SuppressWarnings("deprecation")
public Validator createValidator() throws JAXBException {
throw new UnsupportedOperationException("Not supported yet.");
}
};
Unmarshaller unmarshaller = jc.createUnmarshaller();
m_ddsSettings = (com.ultra.DDSSettings)unmarshaller.unmarshal(new File(xmlfileName));
} catch (UnmarshalException ex) {
Logger.getLogger(UniversalDomainParticipant.class.getName()).log(
Level.SEVERE,
null, ex);
} catch (JAXBException ex) {
Logger.getLogger(UniversalDomainParticipant.class.getName()).log(
Level.SEVERE,
null, ex);
}
Vì vậy, các cách thích hợp để làm xác nhận đây là những gì? Tôi đã mong đợi có một phương thức validate() trên các lớp được tạo bởi JAXB, nhưng tôi đoán điều đó sẽ quá đơn giản đối với Java.
Thú vị, tôi không biết điều đó. Tôi đã tự do thêm một số thông tin vào câu trả lời của bạn, để tham khảo trong tương lai. – skaffman
Thay vì chỉ định rõ ràng URL XMLSchema, theo javadocs, hãy sử dụng giá trị thích hợp từ XMLConstants như được chỉ định tại đây: http://docs.oracle.com/javase/6/docs/api/index.html?javax/xml/validation /Schema.html – icfantv
@icfantv của chúng tôi là đúng, tôi sử dụng: Schema schema = SchemaFactory.newInstance (XMLConstants.W3C_XML_SCHEMA_NS_URI) .newSchema(); // nhưng tham chiếu là: http://docs.oracle.com/javase/6/docs/api/index.html?javax/xml/validation/Schema.html - Ngoài ra điều tôi không hiểu về giải pháp này là url là hằng số: nó không đề cập đến vị trí của lược đồ của chúng ta (không hiển nhiên đối với tôi) – pdem