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

时间:2013-03-19 04:39:39

标签: xslt-1.0 xproc

要求:是在输出xml上添加正确的Doctype声明[输入xml的根元素可以是章节 section 元素]

输入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文件:test.xsl:

  1. 样式表只是将输入xml复制到输出并在所有上添加@sec      元素
  2. 样式表添加了正确的doctype声明来输出xml,因为 输入xml根元素可以是&lt; chapter&gt;要么     &lt;节&GT;元素

    <?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>
    
  3. 预期的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>
    

    使用任何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>
    
        <p:store omit-xml-declaration="false" encoding="utf-8" name="serialize">
            <p:with-option name="href" select="output.xml"/>
        </p:store>
    
    </p:declare-step>
    

2 个答案:

答案 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

希望这有帮助

答案 1 :(得分:0)

这里出现的问题是您在此处创建的doctype是作为XSLT步骤结果的一部分传递给XProc引擎的。但是,它将作为字符数据 传递到 根元素。 XProc不允许这样做。

方法实际上有两个问题:

  • 除非您无法执行任何其他操作,否则请勿使用disable-output-escaping。 xsl:output指令具有创建所需文档类型的完美方法,只需向其添加public-doctype和system-doctype属性即可。
  • XSLT的输出选项将被忽略,因为结果实际上不是由XSLT引擎序列化,而是由XPRoc序列化。因此,您必须将这些doctype属性放在p:store步骤中,以使其在XProc中运行。

HTH!