2011-01-24 81 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)