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

Я пытаюсь установить путь 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)

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
1 255
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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));

Спасибо за помощь мне. Оно работает. У меня есть одна небольшая проблема. Я применяю xsl к карте книги и объединяю несколько тем (файлы xml). Этот код разрешает объект для карты книги. Однако процессор не может найти файлы dtd для отдельных файлов xml. Как установить одно место для всех файлов dtd? Заранее спасибо.

Antony 24.03.2019 15:49

@Antony, поднимите эту проблему как новый вопрос с минимальными, но полными образцами различных файлов, чтобы продемонстрировать проблему, вместе с точным сообщением об ошибке.

Martin Honnen 24.03.2019 15:57

Конечно. Я разместил еще один вопрос здесь: stackoverflow.com/questions/55325569/…

Antony 24.03.2019 16:48

Другие вопросы по теме