如何在XProc中动态生成doctype声明?

时间:2013-03-20 22:42:10

标签: xproc

要求:

  • 是在输出xml上添加正确的Doctype声明[输入xml的根元素可以是章节或节元素]。对于Instance,请考虑chapter元素public identifier是PUBLIC“ - // OASIS // DTD DocBook Chap XML V4.5 // EN”,系统标识符是“chap.dtd”。节元素公共标识符的Simillary是PUBLIC“ - // OASIS // DTD DocBook Sec XML V4.5 // EN”,系统标识符是“sec.dtd”。

输入XML1:chapter.xml

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

输入XML2:section.xml

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

XSLT文件:test.xsl:

样式表只是将输入xml复制到输出,并在所有节元素上添加@sec 样式表添加了正确的doctype声明来输出xml,因为    输入xml根元素可以是元素

<?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 Chap XML V4.5//EN" "chap.dtd"&gt;
</xsl:text>
        </xsl:when>
        <xsl:when test="/section">
            <xsl:text disable-output-escaping="yes">
&lt;!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook Sec XML V4.5//EN" "sec.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>

输入XML1的预期output.xml

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

输入XML2的预期output.xml

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

使用任何XSLT引擎,转换工作绝对正常,并且能够获得预期的输出

但是,如果转换是通过XProc完成的,我最终会遇到以下错误。有人可以帮助解决此错误

错误:XD0001:XD0001如果在步骤输出上生成非XML资源或到达步骤输入,则会出现动态错误。

XProc文件: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>

   <!-- Assume that there is another transform happening for chapter/section xml -->
   <p:xslt version="1.0" name="transform2">
        <p:input port="stylesheet">
            <p:document href="test2.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>

1 个答案:

答案 0 :(得分:1)

再看看

以下两个简单示例显示您不需要对Doctype生成进行上下文化

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

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

[答案后更新]

如果您想要动态更改文档类型

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

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

希望这有帮助