2011-01-24 20 views
5

在我的XML文件,我有一些實體,如’使用JDOM解析與尚未XML文件

所以我創建了一個DTD代碼是針對XML文檔來定義這些在被宣佈外部DTD XML文件實體。以下是用於讀取XML文件的Java代碼。

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);

如何更改Java代碼以通過HTTP檢索DTD以允許解析XML文檔以實現無錯誤?

xml文檔的簡單示例。要做到這一點


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

實體必須聲明就可以使用它們之前。如果您正在使用尚未聲明的實體引用(無論是在文件中還是對外部DTD的引用),那麼您將擁有無效的XML文件。 – 2011-02-10 03:47:09

+1

確實。我的問題是在運行時將我的DTD路徑注入到xml中,因爲在xml文檔中未引用dtd。 DTD駐留在可通過http訪問的遠程服務器上。 – 2011-02-11 14:04:23

回答

3

一種方式是讀文件,然後用變壓器驗證它:

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(); 
     } 
    } 
} 

另一種方法是使用XML標題加上DTD引用來代替XML稱號

替換此:

<?xml version = "1.0"?> 

與此:

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

當然,你只會而不是取代第一次出現嘗試遍歷整個XML文檔

你必須通過傳遞true(生效)給它的構造來實例化SAXBuilder的:

SAXBuilder builder = new SAXBuilder(true); 

或致電:

builder.setValidation(true)