Как я могу установить распознаватель сущностей?

Я пытаюсь установить путь dtd динамически. Когда я использую класс EntityResolver, он работает для org.xml.sax.XMLReader. Но я не знаю, как установить EntityResolver для SAXSource. Как я могу исправить следующий код?

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 (Системе не удается найти указанный файл)


person Antony    schedule 24.03.2019    source источник


Ответы (1)


Есть конструктор

public SAXSource(XMLReader reader,
                 InputSource inputSource)

https://docs.oracle.com/javase/8/docs/api/javax/xml/transform/sax/SAXSource.html#SAXSource-org.xml.sax.XMLReader-org.xml.sax.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));
person Martin Honnen    schedule 24.03.2019
comment
Спасибо за помощь мне. Оно работает. У меня есть одна небольшая проблема. Я применяю xsl к карте книги и объединяю несколько тем (файлы xml). Этот код разрешает объект для карты книги. Однако процессор не может найти файлы dtd для отдельных файлов xml. Как установить одно место для всех файлов dtd? Заранее спасибо. - person Antony; 24.03.2019
comment
@Antony, поднимите эту проблему как новый вопрос с минимальными, но полными образцами различных файлов, чтобы продемонстрировать проблему, вместе с точным сообщением об ошибке. - person Martin Honnen; 24.03.2019
comment
Конечно. Я разместил здесь еще один вопрос: stackoverflow.com/questions/55325569/ - person Antony; 24.03.2019