1

Requirement: Is to add correct Doctype declaration on the output xml [The root element of the input xml can be chapter or section element]

Input XML: chapter.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookx.dtd">
<chapter>
    <title>Chapter Template Title</title>
    <para>Text</para>
    <section>
        <title>Section Title</title>
        <para>Section text</para>
    </section>
</chapter>

XSLT file: test.xsl:

  1. Stylesheet just copies input xml to output and adds @sec on all element
  2. Stylesheet adds correct doctype declaration to output xml, because the input xml root element can be <chapter> or <section> element

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    
    <xsl:template name="add-doctype-declaration">
        <xsl:choose>
            <xsl:when test="/chapter">
                <xsl:text disable-output-escaping="yes">
    &lt;!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookx.dtd"&gt;
    </xsl:text>
            </xsl:when>
            <xsl:when test="/section">
                <xsl:text disable-output-escaping="yes">
    &lt;!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookx.dtd"&gt;
    </xsl:text>
            </xsl:when>
        </xsl:choose>
    </xsl:template>
    
    <xsl:template match="/">
        <xsl:call-template name="add-doctype-declaration"/>
        <xsl:apply-templates/>
    </xsl:template>
    
    <!-- Identity Template -->
    <xsl:template match="@*|*|processing-instruction()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="section">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:attribute name="sec">
                <xsl:number/>
            </xsl:attribute>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
    
    </xsl:stylesheet>
    

Expected output.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookx.dtd">
<chapter>
    <title>Chapter Template Title</title>
    <para>Text</para>
    <section sec="1">
        <title>Section Title</title>
        <para>Section text</para>
    </section>
</chapter>

Using any XSLT engine, the transformation works absolutely fine, and able to get the expected output

But, if the transformation is done through XProc I end up with the following error. Can someone help in resolving this error

err:XD0001 : XD0001 It is a dynamic error if a non-XML resource is produced on a step output or arrives on a step input.

XProc file: test.xpl

<?xml version="1.0" encoding="UTF-8"?>
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc"
    xmlns:c="http://www.w3.org/ns/xproc-step" version="1.0" name="testing">
    <p:input port="source">
       <p:document href="chapter.xml"/>
    </p:input>
    <p:output port="result">
        <p:empty/>
    </p:output>

    <p:xslt version="1.0" name="transform">
        <p:input port="stylesheet">
            <p:document href="test.xsl"/>
        </p:input>
        <p:input port="parameters">
            <p:empty/>
        </p:input>
    </p:xslt>

    <p:store omit-xml-declaration="false" encoding="utf-8" name="serialize">
        <p:with-option name="href" select="output.xml"/>
    </p:store>

</p:declare-step>
grtjn
  • 20,254
  • 1
  • 24
  • 35
suresh
  • 67
  • 5
  • The choose conditon in "add-doctype-declaration" template is mentioned below <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookx.dtd"> <!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookx.dtd"> – suresh Mar 19 '13 at 04:42
  • the xslt is being indented, probably because it is following a numbered list. It is shown properly if you indent the whole with 8 spaces. Fixed it for you.. – grtjn Mar 19 '13 at 06:23

2 Answers2

1

Here is two simple examples that shows that you don't need to contextualize the Doctype generation

Section http://www.sharexml.com/x/get?k=uWn0KA7RThnt

Chapter http://www.sharexml.com/x/get?k=wAJlbUJfzIYQ

Hope this helps

[UPDATED AFTER ANSWER]

And if you want that doctype change dynamically

Section http://www.sharexml.com/x/get?k=pBAwCds86RnQ

Chapter http://www.sharexml.com/x/get?k=JHEWghzgWIq1

Hope this helps

grtjn
  • 20,254
  • 1
  • 24
  • 35
innovimax
  • 440
  • 5
  • 8
0

What goes wrong here is that the doctype you are creating here, is passed as part of the result of the XSLT step to the XProc engine. However, it is passed as character data outside the root element. XProc does not allow this.

There are actually two issues with approach:

  • Don't use disable-output-escaping unless you can't do anything else. The xsl:output instruction has perfect means to create the doctype you want, just add a public-doctype and system-doctype attribute to it.
  • output options of the XSLT will be ignored, as the result isn't actually being serialized by the XSLT engine, but by XPRoc. So you will have to put those doctype attribute on the p:store step, to make it work within XProc.

HTH!

grtjn
  • 20,254
  • 1
  • 24
  • 35
  • Thanks for the response. But, as I have mentioned in the requirements, the root element of input document can be **chapter** or **section**, so correspondingly the **Public** and **System Identifier** values gets changed. I don't get to see a way in adding a dynamic values to **@doctype-public and @doctype-system** on **p:store** step. could you please help – suresh Mar 19 '13 at 20:50
  • @suresh Ah, that wasn't clear from your example. It only showed different root elements in the doctype which is taken care of automatically, but no difference in the public/system identifiers. That can still be done by using a choose in XProc. You can check the root element and make a special case for one of both for instance. If you change the question or create a new one, then I can give a full answer, in case this hint doesn't get you along.. – grtjn Mar 20 '13 at 06:14
  • @ grtjn : New question added at http://stackoverflow.com/questions/15536190/xd0001-it-is-a-dynamic-error-if-a-non-xml-resource-is-produced-on-a-step-output – suresh Mar 21 '13 at 02:33