ValidationException во время генерации PDF из XML с использованием libxslt

Я использую Docbook 1.78 и xsltproc (libxslt 1.1.26 с libxml 2.7.8) в командной строке для создания fo-файла из XML-файла. Моя цель - создать PDF-файл с использованием процессора вывода в формате Apache (fop; версия 1.1). Мой XML-входной файл:

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE book SYSTEM "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<book lang="de" id="MyBook">
    <chapter id="Introduction">
        <title>Introduction</title>
        <section id="sec_intro_1">
            <title>Test</title>
            <para>para1_sec_intro_1 (see also glossary: <xref linkend="gloss_etm-datei"/>).</para>
            <para>para2_sec_intro_1</para>
        </section>
        <section id="sec_intro_2">
            <title>Another Test</title>
            <para>para1_sec_intro_2 (glossary: <xref linkend="gloss_etm-datei"/>).</para> 
            <para>para2_sec_intro2</para>       
        </section>
    </chapter>
    <xi:include href="glossar_test.xml" xmlns:xi="http://www.w3.org/2001/XInclude"></xi:include>
</book>

Если я запускаю следующую команду

xsltproc -o ./test.fo --xinclude --stringparam paper.type A4 --stringparam fop1.extensions 1 ./docbook/fo/docbook.xsl ./test.xml 2> fo_out.txt

Создается fo-файл, но он содержит элементы fo:wrapper с неуникальными идентификаторами. Это сгенерированный fo-файл:

...
(see also glossary: <fo:basic-link internal-destination="gloss_etm-datei"><fo:inline>
            <fo:wrapper id="idp8751564240"><!--ETM-Datei--></fo:wrapper>
            <fo:inline font-weight="bold">ETM-Datei</fo:inline>
        </fo:inline></fo:basic-link>)
....
(glossary: <fo:basic-link internal-destination="gloss_etm-datei"><fo:inline>
            <fo:wrapper id="idp8751564240"><!--ETM-Datei--></fo:wrapper>
            <fo:inline font-weight="bold">ETM-Datei</fo:inline>
        </fo:inline></fo:basic-link>).
...

Теперь, если я попытаюсь сгенерировать pdf-файл из этого fo-файла, fop выдаст исключение:

SEVERE: Exception
org.apache.fop.apps.FOPException: org.apache.fop.fo.ValidationException: Property ID "idp8751564240" (found on "fo:wrapper") previously used; ID values must be unique within a document! (See position 6:48)
javax.xml.transform.TransformerException: org.apache.fop.fo.ValidationException: Property ID "idp8751564240" (found on "fo:wrapper") previously used; ID values must be unique within a document! (See position 6:48)
    at org.apache.fop.cli.InputHandler.transformTo(InputHandler.java:303)
    at org.apache.fop.cli.InputHandler.renderTo(InputHandler.java:130)
    at org.apache.fop.cli.Main.startFOP(Main.java:177)
    at org.apache.fop.cli.Main.main(Main.java:208)
Caused by: javax.xml.transform.TransformerException: org.apache.fop.fo.ValidationException: Property ID "idp8751564240" (found on "fo:wrapper") previously used; ID values must be unique within a document! (See position 6:48)
    at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:501)
    at org.apache.fop.cli.InputHandler.transformTo(InputHandler.java:300)
    ... 3 more
Caused by: org.apache.fop.fo.ValidationException: Property ID "idp8751564240" (found on "fo:wrapper") previously used; ID values must be unique within a document! (See position 6:48)
    at org.apache.fop.events.ValidationExceptionFactory.createException(ValidationExceptionFactory.java:38)
    at org.apache.fop.events.EventExceptionManager.throwException(EventExceptionManager.java:58)
    at org.apache.fop.events.DefaultEventBroadcaster$1.invoke(DefaultEventBroadcaster.java:175)
    at com.sun.proxy.$Proxy2.idNotUnique(Unknown Source)
    at org.apache.fop.fo.FObj.checkId(FObj.java:173)
    at org.apache.fop.fo.FObj.startOfNode(FObj.java:154)
    at org.apache.fop.fo.flow.Wrapper.startOfNode(Wrapper.java:65)
    at org.apache.fop.fo.FOTreeBuilder$MainFOHandler.startElement(FOTreeBuilder.java:325)
    at org.apache.fop.fo.FOTreeBuilder.startElement(FOTreeBuilder.java:175)
    at org.apache.xalan.transformer.TransformerIdentityImpl.startElement(TransformerIdentityImpl.java:1072)
    at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
    at org.apache.xerces.xinclude.XIncludeHandler.startElement(Unknown Source)
    at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
    at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
    at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:484)
    ... 4 more

Я делаю что-то не так здесь? Я ценю любую помощь!

Заранее спасибо!

ИЗМЕНИТЬ Вот файл glosar_test.xml:

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE glossary PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
        "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">

<glossary id="glossar">
    <title>Glossar</title>
    <glossdiv id="gloss_E">
        <title>E</title>
        <glossentry id="gloss_etm-datei">
            <glossterm id="glossterm_etm_datei">
                <indexterm>
                    <primary>ETM-Datei</primary>
                </indexterm>
                <emphasis role="bold">ETM-Datei</emphasis>
            </glossterm>
            <glossdef>
                <para>
                    Glossary_Text
                </para>
            </glossdef>
        </glossentry>

    </glossdiv>
</glossary>

person M F    schedule 28.01.2015    source источник
comment
Можете ли вы также показать glossar_test.xml, содержащий что-то с идентификатором gloss_etm-datei? В противном случае я не могу воспроизвести это.   -  person Mathias Müller    schedule 28.01.2015


Ответы (1)


Я нашел решение! На http://www.sagehill.net/docbookxsl/LinkToGlossary.html это описано как ссылаться на глоассарий. Обычно вы должны использовать тег glossterm, например:

<para>Set your <glossterm linkend="NetAddr">network address</glossterm>.
</para>
...
<glossary>
  <glossentry id="NetAddr">
    <glossterm>Network address</glossterm>
    <glossdef><para>Four numbers separated by periods</para></glossdef>
  </glossentry>
</glossary>

Вы также можете использовать тег link или xref. Если вы используете тег xref, вы должны добавить атрибут id к glossterm и добавить соответствующий атрибут endterm к элементу xref. Например:

<xref linkend="ge-xslfoprocessor" endterm="gt-xslfoprocessor"/>
...

<glossentry id="ge-xslfoprocessor">
<glossterm id="gt-xslfoprocessor">XSL-FO processor</glossterm>
<glossdef>
<para>Software component that converts an XSL-FO document into a
formatted document.</para>
</glossdef>
</glossentry>

Если вы это сделаете, идентификаторы fo:wrapper будут удалены, и fop сможет преобразовать их в файл pdf.

person M F    schedule 28.01.2015