1

要件: 出力xmlに正しいDoctype宣言を追加することです[入力xmlのルート要素はチャプターまたはセクション要素にすることができます]

入力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. 入力xmlルート要素は<chapter>または<section>要素である可能性があるため、スタイルシートは出力xmlに正しいDoctype宣言を追加します

    <?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>
    

期待される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を介して行われる場合、次のエラーが発生します。誰かがこのエラーを解決するのを手伝ってもらえますか

err: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>
4

2 に答える 2

1

Doctype 生成をコンテキスト化する必要がないことを示す 2 つの簡単な例を次に示します。

セクション http://www.sharexml.com/x/get?k=uWn0KA7RThnt

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

お役に立てれば

[回答後に更新]

そして、そのdoctypeを動的に変更したい場合

セクションhttp://www.sharexml.com/x/get?k=pBAwCds86RnQ

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

お役に立てれば

于 2013-03-21T00:01:20.940 に答える
0

ここで問題になるのは、ここで作成しているDoctypeが、XSLTステップの結果の一部としてXProcエンジンに渡されることです。ただし、ルート要素の外部に文字データとして渡されます。XProcはこれを許可していません。

アプローチには実際には2つの問題があります。

  • 他に何もできない場合を除いて、disable-output-escapingを使用しないでください。このxsl:output命令には、public-doctype属性とsystem-doctype属性を追加するだけで、必要なdoctypeを作成するための完璧な手段があります。
  • 結果は実際にはXSLTエンジンではなく、XPRocによってシリアル化されるため、XSLTの出力オプションは無視されます。したがって、XProc内で機能させるには、これらのdoctype属性をp:storeステップに配置する必要があります。

HTH!

于 2013-03-19T06:29:19.127 に答える