2009-07-26 20 views
10

Tôi muốn đọc một tệp XML có khai báo lược đồ trong đó.Làm thế nào để đọc XML được định dạng tốt trong Java, nhưng bỏ qua lược đồ?

Và đó là tất cả những gì tôi muốn làm, hãy đọc nó. Tôi không quan tâm nếu nó hợp lệ, nhưng tôi muốn nó được hình thành tốt.

Vấn đề là người đọc đang cố đọc tệp lược đồ và không thành công.

Tôi thậm chí không muốn thử.

Tôi đã thử vô hiệu xác thực, nhưng nó vẫn khăng khăng cố gắng đọc tệp lược đồ.

Lý tưởng nhất, tôi muốn làm điều này với một Java 5 JDK chứng khoán.

Dưới đây là những gì tôi có cho đến nay, rất đơn giản:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    dbf.setValidating(false); 
    DocumentBuilder db = dbf.newDocumentBuilder(); 
    Document doc = db.parse(file); 

và đây là ngoại lệ Tôi nhận được trở lại:

java.lang.RuntimeException: java.io.IOException: Server returned HTTP response code: 503 for URL: http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd 

Vâng, điều này xảy ra là một lược đồ XHTML, nhưng isn này 't một' XHTML 'vấn đề, nó là một vấn đề XML. Chỉ cần chỉ ra rằng để mọi người không bị phân tâm. Và, trong trường hợp này, W3C về cơ bản là nói "không yêu cầu điều này, đó là một ý tưởng ngớ ngẩn", và tôi đồng ý. Nhưng, một lần nữa, nó là một chi tiết của vấn đề, không phải là gốc rễ của nó. Tôi không muốn hỏi nó TẤT CẢ.

+0

Điều này có vẻ liên quan đến: http://stackoverflow.com/questions/155101/make-documentbuilder-parse-ignore-dtd-references –

Trả lời

13

Các tài liệu tham khảo không phải dành cho Schema, nhưng đối với một DTD.

Tệp DTD có thể chứa nhiều hơn các quy tắc cấu trúc. Chúng cũng có thể chứa các tham chiếu thực thể. Các trình phân tích cú pháp XML có nghĩa vụ tải và phân tích các tham chiếu DTD, vì chúng có thể chứa các tham chiếu thực thể có thể ảnh hưởng đến cách phân tích cú pháp tài liệu và nội dung của tệp (bạn có thể có tham chiếu đối tượng cho các ký tự hoặc cả cụm từ văn bản).

Nếu bạn muốn tránh tải và phân tích cú pháp DTD được tham chiếu, you can provide your own EntityResolver và kiểm tra DTD được tham chiếu và quyết định tải bản sao cục bộ của tệp DTD hay chỉ trả về giá trị rỗng.

Mã mẫu từ câu trả lời giới thiệu trên EntityResolvers tùy chỉnh:

builder.setEntityResolver(new EntityResolver() { 
     @Override 
     public InputSource resolveEntity(String publicId, String systemId) 
       throws SAXException, IOException { 
      if (systemId.contains("foo.dtd")) { 
       return new InputSource(new StringReader("")); 
      } else { 
       return null; 
      } 
     } 
    }); 
+0

Tôi đã nghĩ rằng đây là những gì tôi sẽ phải làm, tôi chỉ đơn giản là thực hiện một "rỗng" EntityResolver mà luôn luôn trả về các InputSource trống cho everthing. Điều này dường như làm các trick. –

+0

Tôi phải đối mặt với cùng một vấn đề và tôi đã áp dụng giải pháp này. Nó giải quyết được IOException. Mối quan tâm của tôi là DOCTYPE đang bị mất với trình quay lại thực thể trống. Tôi muốn DOCTYPE này được giữ lại và không bị xóa khỏi đầu vào. Có thể không. – Rachel

0

Tôi chưa thử nghiệm điều này, nhưng bạn có thể thử gọi setSchema trên nhà máy đi qua null.

ví dụ:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
dbf.setValidating(false); 
dbf.setSchema(null); 
DocumentBuilder db = dbf.newDocumentBuilder(); 
Document doc = db.parse(file); 

Cập nhật: Nhìn vào DocumentBuilderImpl nó trông như thế này có thể làm việc, từ các nhà xây dựng nó sẽ kiểm tra ngữ pháp từ các nhà máy trước khi kiểm tra giản đồ.

Từ DocumentBuilderFactoryImpl:

public void setSchema(Schema grammar) { 
    this.grammar = grammar; 
} 

Từ DocumentBuilderImpl constructor:

... 
this.grammar = dbf.getSchema(); 
if (grammar != null) { 
    XMLParserConfiguration config = domParser.getXMLParserConfiguration(); 
    XMLComponent validatorComponent = null; 
    /** For Xerces grammars, use built-in schema validator. **/ 
    ... 
} 
+0

Rất tiếc, có vẻ như không hoạt động. – jpatokal

1

Vấn đề ở đây không phải là một trong những xác nhận.Bất kể cài đặt xác thực nào, trình phân tích cú pháp vẫn sẽ cố giải quyết mọi tham chiếu trong tài liệu của bạn, chẳng hạn như các thực thể, các DTD và (đôi khi) các lược đồ. Chỉ sau này nó mới quyết định sử dụng chúng (hoặc không). Bạn cần phải cắm vào trình phân giải đối tượng để "chặn" những nỗ lực này khi không tham chiếu.

Kiểm tra Apache XML Resolver để biết cách dễ dàng (ish) để thực hiện việc này.

9

Câu trả lời đơn giản nhất là một-liner, được gọi là sau khi tạo DocumentBuilderFactory:

dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); 

trơ trẽn cribbed từ Make DocumentBuilder.parse ignore DTD references.

Các vấn đề liên quan