2011-01-24 15 views
5

W moim pliku XML Mam kilka podmiotów, takich jak ’Korzystanie JDOM do analizowania pliku XML z DTD zewnętrznego, który nie został zadeklarowany w pliku XML

Więc stworzyli tag DTD dla mojego dokumentu XML do zdefiniowania tych podmioty. Poniżej znajduje się kod Java używany do odczytu pliku XML.

SAXBuilder builder = new SAXBuilder(); 
URL url = new URL("http://127.0.0.1:8080/sample/subject.xml");   
InputStream stream = url.openStream(); 
org.jdom.Document document = builder.build(stream); 

Element root = document.getRootElement(); 

Element name = root.getChild("name"); 
result = name.getText(); 
System.err.println(result);

Jak mogę zmienić kod Java, aby pobrać DTD przez HTTP w celu umożliwienia analizowania mojego dokumentu XML być wolne od błędów?

Uproszczony przykład dokumentu xml.


<main> 
    <name>hello &lsquo; world &rsquo; foo &amp; bar </name> 
</main> 
+1

Podmioty muszą być zadeklarowane, zanim będą mogły być wykorzystane. Jeśli używasz odwołań encji, które nie zostały zadeklarowane (w pliku lub z odwołaniem do zewnętrznego DTD), masz niepoprawny plik XML. –

+1

Rzeczywiście. Moim problemem jest wstrzykiwanie ścieżki do mojego DTD do xml w czasie wykonywania, ponieważ dtd nie jest odwoływany wewnątrz dokumentu xml. DTD znajduje się na zdalnym serwerze dostępnym przez http. –

Odpowiedz

3

Jednym ze sposobów, aby to zrobić byłoby przeczytać dokument, a następnie zatwierdź go z transformatora:

import java.net.URL; 

import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.transform.OutputKeys; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 

import org.w3c.dom.Document; 
import org.xml.sax.SAXException; 
import org.xml.sax.SAXParseException; 

public class ValidateWithExternalDTD { 
    private static final String URL = "http://127.0.0.1:8080/sample/subject.xml"; 
    private static final String DTD = "http://127.0.0.1/YourDTD.dtd"; 

    public static void main(String args[]) { 
     try { 
      DocumentBuilderFactory factory=     DocumentBuilderFactory.newInstance(); 
      factory.setValidating(true); 
      DocumentBuilder builder = factory.newDocumentBuilder(); 

      // Set the error handler 
      builder.setErrorHandler(new org.xml.sax.ErrorHandler() {     
       public void fatalError(SAXParseException spex) 
         throws SAXException { 
        // output error and exit 
        spex.printStackTrace(); 
        System.exit(0); 
       } 

       public void error(SAXParseException spex) 
         throws SAXParseException { 
        // output error and continue 
        spex.printStackTrace(); 
       } 

       public void warning(SAXParseException spex) 
         throws SAXParseException { 
        // output warning and continue 
        spex.printStackTrace(); 
       } 
      }); 

      // Read the document 
      URL url = new URL(ValidateWithExternalDTD.URL); 
      Document xmlDocument = builder.parse(url.openStream()); 
      DOMSource source = new DOMSource(xmlDocument); 

      // Use the tranformer to validate the document 
      StreamResult result = new StreamResult(System.out);      
      TransformerFactory tf = TransformerFactory.newInstance(); 
      Transformer transformer = tf.newTransformer(); 
      transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, ValidateWithExternalDTD.DTD); 
      transformer.transform(source, result); 

      // Process your document if everything is OK 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 
} 

Innym sposobem byłoby zastąpić tytuł XML z tytułem XML plus odniesienia DTD

Wymień to:

<?xml version = "1.0"?> 

z tym:

<?xml version = "1.0"?><!DOCTYPE ...> 

Oczywiście należy zastąpić pierwszy występowaniu gazów i nie próbować przejść przez cały dokument XML

Musisz instancję SAXBuilder przekazując prawdziwe (validate) do konstruktora:

SAXBuilder builder = new SAXBuilder(true); 

lub zadzwoń:

builder.setValidation(true) 
+1

Jak duży jest rozmiar XML? – DaTroop

+1

Jak duży jest rozmiar XML? Czy mogę prosić o próbkę XML? Czy dokument XML zawsze zawiera tytuł XML? – DaTroop

+0

Używam JDOM w przeciwieństwie do W3C DOM :( –