При объединении нескольких XML-файлов, как я могу установить EntityResolver для дочерних XML-файлов, кроме родительского XML? - PullRequest
0 голосов
/ 24 марта 2019

У меня есть файл книги xml, который ссылается на несколько других файлов XML. Когда я пытаюсь запустить xslt для файла book.xml, EntityResolver в моем коде разрешает путь dtd. Однако для дочерних XML-файлов, которые объединяются, пути dtd не разрешаются.

Пример sample_book.ditamap

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE bookmap PUBLIC "-//OASIS//DTD DITA BookMap//EN" "bookmap.dtd">
<bookmap>
    <booktitle>
        <mainbooktitle>sample book</mainbooktitle>
    </booktitle>
    <part navtitle="Overview">
        <topicref href="../topics/introduction.dita"/>
        <topicref href="../topics/install.dita"/>
    </part>
</bookmap>

`

Java-код

public class XMLProcessor  {

       public void transform(String xmlf, String xslf) throws TransformerConfigurationException, TransformerException, org.xml.sax.SAXException, IOException{

        org.xml.sax.XMLReader reader = XMLReaderFactory.createXMLReader();
        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:/sample/dtd/bookmap.dtd");
                }

                return null;
                }
            };
        // sour.setPublicId("file:///D:/sample/dtd/bookmap/dtd/bookmap.dtd");


            reader.setEntityResolver(ent);
            SAXSource source = new SAXSource(reader, new InputSource(xmlf));
            //reader.parse(new InputSource(xmlf));
         //StreamSource sourcedoc = new StreamSource(xmlf);
         transformer = factory.newTransformer(stylesheet);

        try {
            transformer.transform(source, new StreamResult(new FileWriter("D:\\sample\\out\\result.xml")));
        } catch (IOException ex) {
            Logger.getLogger(XMLProcessor.class.getName()).log(Level.SEVERE, null, ex);
        }

    }





}`

Ожидаемый результат

`

<?xml version="1.0" encoding="UTF-8"?>
<pages xmlns:mf="urn:mf">
    <parentpage>
        <parentpagename>sample book</parentpagename>
    </parentpage>
    <part>
        <partname>Overview</partname>
        <text/>
        <level-2>
            <concept xmlns:ditaarch="http://dita.oasis-open.org/architecture/2005/"
                id="introduction" ditaarch:DITAArchVersion="1.3"
                domains="(topic concept)                            (topic abbrev-d)                            a(props deliveryTarget)                            (topic equation-d)                            (topic hazard-d)                            (topic hi-d)                            (topic indexing-d)                            (topic markup-d)                            (topic mathml-d)                            (topic pr-d)                            (topic relmgmt-d)                            (topic sw-d)                            (topic svg-d)                            (topic ui-d)                            (topic ut-d)                            (topic markup-d xml-d)   "
                class="- topic/topic concept/concept ">
                <title class="- topic/title ">Introduction</title>
                <shortdesc class="- topic/shortdesc "/>
                <conbody class="- topic/body  concept/conbody ">
                    <p class="- topic/p ">Sample introduction</p>
                </conbody>
            </concept>
        </level-2>
        <text/>
        <level-2>
            <task xmlns:ditaarch="http://dita.oasis-open.org/architecture/2005/" id="install"
                ditaarch:DITAArchVersion="1.3"
                domains="(topic task)                            (topic abbrev-d)                            a(props deliveryTarget)                            (topic equation-d)                            (topic hazard-d)                            (topic hi-d)                            (topic indexing-d)                            (topic markup-d)                            (topic mathml-d)                            (topic pr-d)                            (topic relmgmt-d)                            (topic sw-d)                            (topic svg-d)                            (topic ui-d)                            (topic ut-d)                            (topic markup-d xml-d)                            (topic task strictTaskbody-c)   "
                class="- topic/topic task/task ">
                <title class="- topic/title ">Install</title>
                <shortdesc class="- topic/shortdesc "/>
                <taskbody class="- topic/body task/taskbody ">
                    <context class="- topic/section task/context ">
                        <p class="- topic/p ">Download xyz installer from here. </p>
                    </context>
                    <steps class="- topic/ol task/steps ">
                        <step class="- topic/li task/step ">
                            <cmd class="- topic/ph task/cmd ">Double-click the downloader
                                installer.</cmd>
                        </step>
                        <step class="- topic/li task/step ">
                            <cmd class="- topic/ph task/cmd ">Do this.</cmd>
                        </step>
                        <step class="- topic/li task/step ">
                            <cmd class="- topic/ph task/cmd ">Do that</cmd>
                        </step>
                    </steps>
                </taskbody>
            </task>
        </level-2>
    </part>
</pages>

`

Фактический результат

При запуске XSLT отображается следующее сообщение об ошибке. Ошибка исчезает, когда я перемещаю файлы dtd в папку с темами.

Warning   XTDE0540: Ambiguous rule match for /bookmap/booktitle[1] Matches both "element(Q{}booktitle)" on line 54 of
>file:///D:/sample/xsl/merge.xsl and "element(Q{}booktitle)" on line 18 of >file:///D:/sample/xsl/merge.xsl Warning at char 11 in

xsl: apply-templates / @ выберите в строке 30 столбца 104 из> merge.xsl: FODC0002: ошибка ввода-вывода при обработке синтаксического анализатора XML Файл: / D: /sample/sampledoc/topics/introduction.dita: D: \ sample \ sampledoc \ themes \ concept.dtd (система не может найти

* Указан файл

Предупреждение на символ 11 в xsl: apply-templates / @ select в строке 30 столбца 104 из> merge.xsl: FODC0002: ошибка ввода-вывода, о которой сообщает Файл обработки синтаксического анализатора XML: / D: /sample/sampledoc/topics/install.dita: D: \ sample \ sampledoc \ themes \ task.dtd (система не может найти файл> указано)

Ответы [ 2 ]

1 голос
/ 24 марта 2019

Вы можете установить URIResolver на Transformer, который будет вызываться, когда ваш XSLT-код вызывает doc () или document () для выборки указанных файлов XML.Затем URIResolver может установить EntityResolver в синтаксическом анализаторе XML, используемом для анализа этих файлов.

В качестве альтернативы вы можете сделать все это с помощью Apache XMLResolver, который использует URI как на уровне XSLT, так и на уровне XML, ссылаясь на каталогфайл в формате, определенном OASIS.

0 голосов
/ 25 марта 2019

Благодаря Майклу я смог решить эту проблему.

  1. Добавлен файл CatalogManager.properties в classpath.

  2. Создан файл catalog.xml со всеми открытыми идентификаторами.

    public class XMLProcessor  {
    
       public void transform(String xmlf, String xslf, String outpath) throws TransformerConfigurationException, TransformerException, org.xml.sax.SAXException, IOException{
    
        org.xml.sax.XMLReader reader = XMLReaderFactory.createXMLReader();
        Transformer transformer = null;
        TransformerFactory factory = TransformerFactory.newInstance();
    
         StreamSource stylesheet = new StreamSource(xslf);
    
            CatalogResolver cr = new CatalogResolver();
            reader.setEntityResolver(cr);
            factory.setURIResolver(cr);
    
            SAXSource source = new SAXSource(reader, new InputSource(xmlf));
    
         transformer = factory.newTransformer(stylesheet);
    
        try {
            transformer.transform(source, new StreamResult(new FileWriter(outpath)));
        } catch (IOException ex) {
            Logger.getLogger(XMLProcessor.class.getName()).log(Level.SEVERE, null, ex);
        }
    
    }
    

    }

...