2009-10-30 21 views
7

Tôi muốn phân tích các tài liệu XML sau đây để giải quyết tất cả các đơn vị trong đó:Java: Làm thế nào để ngăn chặn 'systemId' trong EntityResolver # resolveEntity (String publicId, String systemId) khỏi bị tuyệt đối đến thư mục làm việc hiện tại

<!DOCTYPE doc SYSTEM 'mydoc.dtd'> 
<doc>&title;</doc> 

EntityResolver tôi có nghĩa vụ phải lấy thực thể bên ngoài với ID hệ thống nhất định từ cơ sở dữ liệu và sau đó làm nghị quyết, xem dưới đây để minh họa:

private static class MyEntityResolver 
{ 
    public InputSource resolveEntity(String publicId, String systemId) 
     throws SAXException, IOException 
    { 
     // At this point, systemId is always absolutized to the current working directory, 
     // even though the XML document specified it as relative. 
     // E.g. "file:///H:/mydoc.dtd" instead of just "mydoc.dtd" 
     // Why??? How can I prevent this??? 

     SgmlEntity entity = findEntityFromDatabase(systemId); 
     InputSource is = new InputSource(new ByteArrayInputStream(entity.getContents())); 
     is.setPublicId(publicId); 
     is.setSystemId(systemId); 
     return is; 
    } 
} 

tôi đã cố gắng cả hai sử dụng DOM (DocumentBuilder) và SAX (XMLReader) , đặt trình phân giải đối tượng thành MyEnt ityResolver (tức là setEntityResolver(new MyEntityResolver())), nhưng systemId trong MyEntityResolver#resolveEntity(String publicId, String systemId) luôn được tuyệt đối với thư mục làm việc hiện tại.

Tôi cũng đã thử gọi số setFeature("http://xml.org/sax/features/resolve-dtd-uris", false);, nhưng điều đó không giúp được gì.

Vậy làm cách nào tôi có thể đạt được những gì tôi muốn?

Cảm ơn!

Trả lời

7

Rõ ràng, có một giao diện khác có tên là EntityResolver2 là phần mở rộng của số EntityResolver cũ. (Nói về tên khó hiểu!)

Dù sao, tôi thấy rằng EntityResolver2 đạt được những gì tôi muốn, nghĩa là nó không thực hiện bất kỳ thay đổi nào đối với systemId, vì vậy nó luôn chính xác là những gì được chỉ định trong tài liệu XML.

0

Từ the EntityResolver Javadocs:

Nếu nhận dạng hệ thống là một URL, phân tích cú pháp SAX phải giải quyết nó hoàn toàn trước khi báo cáo nó vào ứng dụng .

Ngoài ra, các org.xml.sax docs có điều này để nói về tính năng quyết tâm-dtd-URI:

Nó không áp dụng đối với EntityResolver.resolveEntity(), mà không được sử dụng để báo cáo tờ khai. ..

Tôi nghĩ bạn phải đặt URI cơ sở của mình thành thứ bạn có thể sống hoặc sử dụng ID công khai thay vì ID hệ thống.

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