2009-07-08 12 views

Odpowiedz

25

W idealnym świecie można sprawdzić poprawność za pomocą Validator. Coś takiego:

SchemaFactory schemaFactory = SchemaFactory 
    .newInstance(XMLConstants.XML_DTD_NS_URI); 
Schema schema = schemaFactory.newSchema(new File(
    "xmlValidate.dtd")); 
Validator validator = schema.newValidator(); 
validator.validate(new StreamSource("xmlValidate.xml")); 

Niestety, implementacja Sun (przynajmniej, jak Java 6) nie obejmują wsparcie dla tworzenia instancji schematu z DTD. Być może uda Ci się wyśledzić implementację innej firmy.

Najlepszym rozwiązaniem może być zmiana dokumentu tak, aby zawierał DTD przed analizą za pomocą innego mechanizmu.


Można użyć transformer wstawić deklaracji DTD:

TransformerFactory tf = TransformerFactory 
    .newInstance(); 
Transformer transformer = tf.newTransformer(); 
transformer.setOutputProperty(
    OutputKeys.DOCTYPE_SYSTEM, "xmlValidate.dtd"); 
transformer.transform(new StreamSource(
    "xmlValidate.xml"), new StreamResult(System.out)); 

... ale to nie wydaje się, aby zastąpić istniejący deklaracji DTD.


Ten StAX czytelnik zdarzenie może wykonać zadanie:

public static class DTDReplacer extends 
     EventReaderDelegate { 

    private final XMLEvent dtd; 
    private boolean sendDtd = false; 

    public DTDReplacer(XMLEventReader reader, XMLEvent dtd) { 
     super(reader); 
     if (dtd.getEventType() != XMLEvent.DTD) { 
     throw new IllegalArgumentException("" + dtd); 
     } 
     this.dtd = dtd; 
    } 

    @Override 
    public XMLEvent nextEvent() throws XMLStreamException { 
     if (sendDtd) { 
     sendDtd = false; 
     return dtd; 
     } 
     XMLEvent evt = super.nextEvent(); 
     if (evt.getEventType() == XMLEvent.START_DOCUMENT) { 
     sendDtd = true; 
     } else if (evt.getEventType() == XMLEvent.DTD) { 
     // discard old DTD 
     return super.nextEvent(); 
     } 
     return evt; 
    } 

    } 

Będzie wysłać daną deklarację DTD tuż po rozpoczęciu dokumentu i wyrzucić każdy ze starego dokumentu.

Wykorzystanie Demo:

XMLEventFactory eventFactory = XMLEventFactory.newInstance(); 
XMLEvent dtd = eventFactory 
    .createDTD("<!DOCTYPE Employee SYSTEM \"xmlValidate.dtd\">"); 

XMLInputFactory inFactory = XMLInputFactory.newInstance(); 
XMLOutputFactory outFactory = XMLOutputFactory.newInstance(); 
XMLEventReader reader = inFactory 
    .createXMLEventReader(new StreamSource(
     "xmlValidate.xml")); 
reader = new DTDReplacer(reader, dtd); 
XMLEventWriter writer = outFactory.createXMLEventWriter(System.out); 
writer.add(reader); 
writer.flush(); 

// TODO error and proper stream handling 

Zauważ, że XMLEventReader mogłyby stanowić źródło dla innego mechanizmu transformacji, który przeprowadził weryfikację.


Znacznie łatwiej byłoby sprawdzić poprawność za pomocą schematu W3, jeśli masz taką opcję.

+0

Dziękuję bardzo za wyczerpującą odpowiedź, która bardzo mi pomaga. Spróbuję przekonwertować DTD na schemat W3, ponieważ mogę wtedy użyć Validatora Słońca. – Simon

+0

mój plik XML nie zawiera deklaracji DOCTYPE. i parsuję plik używając SAXParser w systemie Android. DTD generowane przeze mnie. Jak mogę sprawdzić poprawność pliku XML za pomocą mojego DTD, w analizie SAX? –

+0

@ Chusbu - byłoby lepiej, gdybyś zadał nowe pytanie. – McDowell

1

Musisz wdrożyć EntityResolver, kasy this example.

+0

Dziękuję za pomoc, ale co, jeśli w ogóle nie określono DOCTYPE? EntityResolver nie pomógłby mi w tym przypadku, prawda? – Simon

+0

@ Bluegene: Na co walczysz, jeśli nie ma DOCTYPE? –

+0

Wbrew własnemu DTD. Po prostu chcę się upewnić, że otrzymany kod XML jest zgodny z _my_ DTD, a nie tylko z DTD, który określa nadawca. – Simon

3

im całkiem pewny, że wspomniany materiał będzie działać ..

Dzięki za pomoc, ale co jeśli nie DOCTYPE został określony w wszystkich? EntityResolver nie pomógłby mi w tym przypadku, prawda? - Simon Jul 8 '09 o 6:34

@Bluegene: Na co walczysz, jeśli nie ma DOCTYPE? - J-16 SDiZ Jul 8 '09 o 7:12

Przeciwko mojej własnej definicji DTD. Chcę tylko upewnić się, że kod XML, który otrzymuję, jest zgodny z moim DTD, a nie tylko z DTD, który określa nadawca.- Simon lipca 8 '09 na 23:09

czy problem ma to zostać zatwierdzone przed swoim DTD zamiast autorów należy upewnić się, że nie jest jasne, że dokumentacja szczegóły doctype, a co musi być w pliku xml

Powiązane problemy