Potrzebuję do sprawdzania poprawności moich obiektów JAXB przed zestawieniem do pliku XML. Przed wersją JAXB 2.0 można było użyć javax.xml.bind.Validator. Ale to jest przestarzałe, więc staram się wymyślić właściwy sposób robienia tego. Jestem zaznajomiony z walidacją w czasie marshall, ale w moim przypadku po prostu chcę wiedzieć, czy jest ważna. Przypuszczam, że mógłbym wysłać do pliku tymczasowego lub pamięci i wyrzucić go, ale zastanawiam się, czy istnieje bardziej eleganckie rozwiązanie.Jak sprawdzić poprawność w stosunku do schematu w JAXB 2.0 bez zestawiania?
Odpowiedz
Po pierwsze, javax.xml.bind.Validator
został wycofany na rzecz javax.xml.validation.Schema
(javadoc). Chodzi o to, że analizujesz swój schemat przez javax.xml.validation.SchemaFactory
(javadoc) i wstrzykujesz go do marshaller/unmarshaller.
Jeśli chodzi o pytanie dotyczące sprawdzania poprawności bez zestawiania, problem polega na tym, że JAXB faktycznie deleguje walidację do Xerces (lub dowolnego procesora SAX, którego używasz), a Xerces sprawdza twój dokument jako strumień zdarzeń SAX. Aby przeprowadzić walidację, musisz wykonać rodzaj kołysania.
Najniższą implementacją tego rozwiązania byłoby użycie implementacji "/ dev/null" procesora SAX. Przekazywanie do wartości zerowej OutputStream nadal wymagałoby generowania XML, co jest marnotrawstwem. Więc proponuję:
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(locationOfMySchema);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setSchema(schema);
marshaller.marshal(objectToMarshal, new DefaultHandler());
DefaultHandler
anuluje wszystkie zdarzenia, a operacja marshal()
rzuci JAXBException jeśli sprawdzanie poprawności przeciwko schematu nie powiedzie się.
To jak to zrobiliśmy. Musiałem znaleźć sposób sprawdzenia poprawności pliku xml w stosunku do xsd odpowiadającego wersji xml, ponieważ mamy wiele aplikacji używających różnych wersji zawartości xml.
Tak naprawdę nie znalazłem żadnych dobrych przykładów w sieci i ostatecznie skończyłem z tym. Mam nadzieję, że to pomoże.
ValidationEventCollector vec = new ValidationEventCollector();
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
URL xsdURL = getClass().getResource("/xsd/" + xsd);
Schema schema = sf.newSchema(xsdURL);
//You should change your jaxbContext here for your stuff....
Unmarshaller um = (getJAXBContext(NotificationReponseEnum.NOTIFICATION, notificationWrapper.getEnteteNotification().getTypeNotification()))
.createUnmarshaller();
um.setSchema(schema);
try {
StringReader reader = new StringReader(xml);
um.setEventHandler(vec);
um.unmarshal(reader);
} catch (javax.xml.bind.UnmarshalException ex) {
if (vec != null && vec.hasEvents()) {
erreurs = new ArrayList <MessageErreur>();
for (ValidationEvent ve: vec.getEvents()) {
MessageErreur erreur = new MessageErreur();
String msg = ve.getMessage();
ValidationEventLocator vel = ve.getLocator();
int numLigne = vel.getLineNumber();
int numColonne = vel.getColumnNumber();
erreur.setMessage(msg);
msgErreur.setCode(ve.getSeverity())
erreur.setException(ve.getLinkedException());
erreur.setPosition(numLigne, numColonne);
erreurs.add(erreur);
logger.debug("Erreur de validation xml" + "erreur : " + numLigne + "." + numColonne + ": " + msg);
}
}
}
można użyć javax.xml.bind.util.JAXBSource
(javadoc) i javax.xml.validation.Validator
(javadoc), rzucać w realizacji org.xml.sax.ErrorHandler
(javadoc) i wykonaj następujące czynności:
import java.io.File;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.util.JAXBSource;
import javax.xml.validation.*;
public class Demo {
public static void main(String[] args) throws Exception {
Customer customer = new Customer();
customer.setName("Jane Doe");
customer.getPhoneNumbers().add(new PhoneNumber());
customer.getPhoneNumbers().add(new PhoneNumber());
customer.getPhoneNumbers().add(new PhoneNumber());
JAXBContext jc = JAXBContext.newInstance(Customer.class);
JAXBSource source = new JAXBSource(jc, customer);
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new File("customer.xsd"));
Validator validator = schema.newValidator();
validator.setErrorHandler(new MyErrorHandler());
validator.validate(source);
}
}
Aby uzyskać więcej informacji, zobacz moje Blog
- 1. Dlaczego JAXB potrzebuje konstruktora bez argumentów do zestawiania?
- 2. jak mogę wycofać w JAXB i cieszyć się sprawdzanie poprawności schematu bez używania wyraźnej plik schematu
- 3. Jak sprawdzić poprawność struktury (lub schematu) słownika w Pythonie?
- 4. Moxy JAXB: Jak wykluczyć elementy z zestawiania
- 5. Sprawdź poprawność schematu XSD?
- 6. Jak można programowo sprawdzić poprawność ciągu JSON względem schematu?
- 7. Jak mogę sprawdzić poprawność wyjścia XmlSerializer?
- 8. Jak sprawdzić poprawność tablicy?
- 9. Jak uniemożliwić JAXB zapisywanie nieużywanych przestrzeni nazw podczas zestawiania
- 10. usuń atrybut xmlns od elementu głównego podczas zestawiania JAXB
- 11. Jak sprawdzić poprawność obiektu JSON w java?
- 12. Jak sprawdzić poprawność daty MYSQL w PHP?
- 13. Jak sprawdzić poprawność wybranej wartości w DropDownList?
- 14. Jak sprawdzić poprawność adresu IP w Pythonie?
- 15. Jak sprawdzić poprawność pola wyboru w nokaucie
- 16. Jak sprawdzić poprawność wyrażenia regularnego?
- 17. Jak sprawdzić poprawność przychodzących danych JSON w usłudze REST?
- 18. Jak sprawdzić poprawność XHTML za pomocą nokogiri?
- 19. Czy można zwalidować sformatowany XML z JAXB 2.0?
- 20. Ruby on Rails: Jak sprawdzić poprawność modelu bez Active Record?
- 21. W jaki sposób można sprawdzić poprawność schematu pliku XML za pomocą Scala?
- 22. Czy Oracle może sprawdzić poprawność XML za pomocą schematu XSD w lokalnym systemie plików?
- 23. Jak sprawdzić poprawność tekstu nie jest pusty w Rails
- 24. Elixir Ecto: Jak sprawdzić poprawność klucza obcego?
- 25. jak sprawdzić poprawność identyfikatora powiązanego modelu?
- 26. dodawanie adnotacji do klasy wiązania JAXB od schematu
- 27. Jak "sprawdzić poprawność" NSTimer po unieważnieniu go?
- 28. Jak sprawdzić poprawność dwóch pól dla unikalności
- 29. Jak sprawdzić poprawność XML (przez plik XSD) w Haskell?
- 30. Jak sprawdzić poprawność pola przy aktualizacji w DRF?
Jedna z kwestii związanych z tym podejściem: w przypadku tej metody nie można uzyskać informacji o numerze wiersza/kolumnie na temat błędów sprawdzania poprawności, dlatego trudno jest prześledzić problemy. –
Czy to podejście ma zastosowanie do Unmarchalling. Nie mogę utworzyć obiektu JAXBSource. – Xelian