Я пытаюсь установить путь dtd динамически. Когда я использую класс EntityResolver, он работает для org.xml.sax.XMLReader. Но я не знаю, как установить EntityResolver для SAXИсточник. Как я могу исправить следующий код?
import java.util.logging.Logger;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
public class XMLProcessor {
public void transform(String xmlf, String xslf) throws TransformerConfigurationException, TransformerException, org.xml.sax.SAXException, IOException{
Transformer transformer;
TransformerFactory factory = TransformerFactory.newInstance();
StreamSource stylesheet = new StreamSource(xslf);
//Source source = StreamSource(xmlf);
SAXSource source = new SAXSource(new InputSource(xmlf));
org.xml.sax.XMLReader reader = XMLReaderFactory.createXMLReader();
EntityResolver ent = new EntityResolver() {
@Override
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
System.out.println(publicId);
System.out.println(systemId);
if (publicId.equals("-//OASIS//DTD DITA BookMap//EN")){
return new InputSource("file:///D:/dtd/bookmap/dtd/bookmap.dtd");
}
if (systemId.equals("file:///D:/doc/maps/bookmap.dtd")){
return new InputSource("file:////dtd/bookmap/dtd/bookmap.dtd");
}
return null;
}
};
// sour.setPublicId("file:///D:/dtd/bookmap/dtd/bookmap.dtd");
reader.setEntityResolver(ent);
reader.parse(new InputSource(xmlf));
//StreamSource sourcedoc = new StreamSource(xmlf);
transformer = factory.newTransformer(stylesheet);
try {
transformer.transform(source, new StreamResult(new FileWriter("out/result.xml")));
} catch (IOException ex) {
Logger.getLogger(XMLProcessor.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Разрешение объекта, кажется, работает для этой строки:
reader.parse(new InputSource(xmlf));
Но следующая строка не работает:
transformer.transform(source, new StreamResult(new FileWriter("out/result.xml")));
и я получаю эту ошибку:
doc\maps\bookmap.dtd (The system cannot find the file specified)




Есть конструктор
public SAXSource(XMLReader reader,
InputSource inputSource)
так что вы должны быть в состоянии использовать
org.xml.sax.XMLReader reader = XMLReaderFactory.createXMLReader();
EntityResolver ent = new EntityResolver() {
@Override
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
System.out.println(publicId);
System.out.println(systemId);
if (publicId.equals("-//OASIS//DTD DITA BookMap//EN")){
return new InputSource("file:///D:/dtd/bookmap/dtd/bookmap.dtd");
}
if (systemId.equals("file:///D:/doc/maps/bookmap.dtd")){
return new InputSource("file:////dtd/bookmap/dtd/bookmap.dtd");
}
return null;
}
};
reader.setEntityResolver(ent);
SAXSource source = new SAXSource(reader, new InputSource(xmlf));
@Antony, поднимите эту проблему как новый вопрос с минимальными, но полными образцами различных файлов, чтобы продемонстрировать проблему, вместе с точным сообщением об ошибке.
Конечно. Я разместил еще один вопрос здесь: stackoverflow.com/questions/55325569/…
Спасибо за помощь мне. Оно работает. У меня есть одна небольшая проблема. Я применяю xsl к карте книги и объединяю несколько тем (файлы xml). Этот код разрешает объект для карты книги. Однако процессор не может найти файлы dtd для отдельных файлов xml. Как установить одно место для всех файлов dtd? Заранее спасибо.