2012-04-16 17 views
4

XMLをePubに変換するためのパッケージを作成しました。空の名前空間(xmlns="")ノードが結果ドキュメントに書き込まれる場合を除いて、すべて正常に動作します。変換の前に、主セグメント(すなわち、meta,など)を保持するための一時変数を準備し、最後にノード(xsl:copy-of[@copy-namespaces='no']を使用)をresult-documentにコピーしました。また@exclude-result-prefixes='ns_list_sep_by_space'xsl:transformの要素内に使用しても、依然として望ましい結果を得ることができませんでした。 XSLを使用している場合空白/空白の名前空間宣言がresult-document内で生成されています

酸素IDEは言ってポップアップでメッセージを示しても、彼らはコピーを指定することにより、除外されない限り、オリジナルの要素ノードからコピーされた名前空間ノードを持つことになり、新たな要素をコピーします-namespaces = "no"この属性が省略された場合、または値がyesの場合、元の要素のすべての名前空間ノードが新しい要素にコピーされます。値がnoの場合は、名前空間ノードは何もコピーされません。ただし、名前空間固定化プロセスの要求に従って、名前空間ノードは依然として結果ツリーに作成されます。ここで


私の問題のいくつかの詳細は次のとおりです。

メインのスタイルシート:
main.xsl:main caller

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" 
    xmlns:cylian="local-ns-for-extension-functions" 
    exclude-result-prefixes="xs xd cylian" 
    version="2.0"> 

    <xsl:import href="modules/core.xsl"/> 

    <xsl:variable name="base" select="base-uri()" as="xs:anyURI"/> 

    <xsl:template match="/"> 
     <xsl:call-template name="procA"/> 
    </xsl:template> 

</xsl:transform> 

メインのスタイルシート:
core.xsl: core processing unit

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     xmlns:xs="http://www.w3.org/2001/XMLSchema" 
     xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" 
     xmlns:cylian="local-ns-for-extension-functions" 
     exclude-result-prefixes="xs xd cylian" 
     version="2.0"> 

     <xsl:import href="sub1.xsl"/> 
     <xsl:import href="sub2.xsl"/> 
     <!--and more--> 

     <!-- variable to hold intermediate results for stage1 --> 
     <xsl:variable name="stage1"> 
      <cylianz> 
       <xsl:copy-of select="$a" copy-namespaces="no"/> 
       <xsl:copy-of select="$b" copy-namespaces="no"/> 
       <!--and more--> 
      </cylianz> 
     </xsl:variable> 

     <!-- variable to hold intermediate results for stage2 --> 
     <xsl:variable name="stage2"> 
      <cylianz> 
      <xsl:for-each select="$stage1//cylian"> 
       <xsl:sort select="@pos"/> 
       <xsl:sequence select="."/> 
      </xsl:for-each> 
      </cylianz> 
     </xsl:variable> 
     <xsl:template name="procA"> 
      <xsl:for-each select="$stage2//cylian"> 
       <xsl:result-document href="{concat($outdir,@href)}" format="general"> 
        <xsl:call-template name="procB"> 
         <xsl:with-param name="context" select="."/> 
         <xsl:with-param name="title"> 
          <xsl:value-of select="$book_title"/> 
         </xsl:with-param> 
        </xsl:call-template> 
       </xsl:result-document> 
      </xsl:for-each> 
     </xsl:template> 
    <xsl:template name="procB"> 
     <xsl:param name="context"/> 
     <xsl:param name="title"/> 
     <html xmlns="http://www.w3.org/1999/xhtml"> 
     <head> 
       <xsl:call-template name="header"> 
        <xsl:with-param name="title" select="$title"/> 
       </xsl:call-template> 
     </head> 
     <body> 
       <div id="root"> 
        <xsl:apply-templates select="."/> 
       </div> 
     </body> 
    </html> 
</xsl:template> 

<!-- 
1/ other rules are shortened for clarity 
2/ declaration «xmlns:cylian='local-ns-for-extension-functions'» has to retain, some parts of transformation uses some extension functions from that namespace 
--> 

</xsl:transform> 
a.html

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE html 
    PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
     <meta xmlns="" http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 
     <title xmlns="">BookTitle</title> 
      <!-- 
       2012.04.16 - 18:27:36 [XSLT processor: SAXON 9.1.0.5 from Saxonica] 
      --> 
     <link xmlns="" href="isbn.css" type="text/css" rel="stylesheet"/> 
    </head> 
    <body> 
     <div id="root"> 
     <div xmlns="" id="a1"> 
      <!--...--> 
     </div> 
     </div> 
    </body> 
</html> 

私は問題が起こっているのですかを理解しやすくなるでしょう願っています:

、ここでは出力です。すべての提案は大歓迎です。前もって感謝します。

+0

Cylianは、あなたは 'のxmlns =" HTTPを配置する必要があります。XHTML要素を作成するすべてのスタイルシートモジュールの 'xsl:stylesheet'要素の' xsl:stylesheet'要素に 'org/1999/xhtml' 'を置き換えます。 –

+0

この質問は原則的には良いですが、 xml/xslを最小限の例にしてください – oberlies

答えて

4

あなたのコードを確認する必要がありますが、私はあなたが持っていると思われます。

<xsl:template match="/"> 
    <foo xmlns="http://example.com/ns"> 
    <xsl:apply-templates/> 
    </foo> 
</xsl:template> 

<xsl:template match="whatever"> 
    <bar/> 
</xsl:template> 

、あなたが

<foo xmlns="http://example.com/ns"> 
    <bar/> 
</foo> 

あなたはXSLにデフォルトの名前空間宣言を移動していることを確認し問題を解決したい一方で、あなたは

<foo xmlns="http://example.com/ns"> 
    <bar xmlns=""/> 
</foo> 

を得る:stylesheet要素を、例えばと

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns="http://example.com/ns"> 
    version="1.0"> 

    <xsl:template match="/"> 
     <foo> 
     <xsl:apply-templates/> 
     </foo> 
    </xsl:template> 

    <xsl:template match="whatever"> 
     <bar/> 
    </xsl:template> 

</xsl:stylesheet> 

このように、異なるテンプレートで作成されたすべての結果要素に適用されます。

[編集]あなただけが必ずxsl:stylesheetxmlns="http://www.w3.org/1999/xhtml"入れているすべてのスタイルシートモジュールことを確認する必要がありますいくつかのファイルで、私は私の提案は正しいと思う今提供してきたサンプルに基づいて それぞれxsl:transform要素すべての結果となるよう要素はXHTML名前空間になります。

[第二編集] 私はあなたが

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:xs="http://www.w3.org/2001/XMLSchema" 
     xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" 
     xmlns:cylian="local-ns-for-extension-functions" 
     exclude-result-prefixes="xs xd cylian" 
     version="2.0"> 

     <xsl:import href="sub1.xsl"/> 
     <xsl:import href="sub2.xsl"/> 
     <!--and more--> 

     <!-- variable to hold intermediate results for stage1 --> 
     <xsl:variable name="stage1" xmlns=""> 
      <cylianz> 
       <xsl:copy-of select="$a" copy-namespaces="no"/> 
       <xsl:copy-of select="$b" copy-namespaces="no"/> 
       <!--and more--> 
      </cylianz> 
     </xsl:variable> 

     <!-- variable to hold intermediate results for stage2 --> 
     <xsl:variable name="stage2" xmlns=""> 
      <cylianz> 
      <xsl:for-each select="$stage1//cylian"> 
       <xsl:sort select="@pos"/> 
       <xsl:sequence select="."/> 
      </xsl:for-each> 
      </cylianz> 
     </xsl:variable> 
     <xsl:template name="procA"> 
      <xsl:for-each select="$stage2//cylian"> 
       <xsl:result-document href="{concat($outdir,@href)}" format="general"> 
        <xsl:call-template name="procB"> 
         <xsl:with-param name="context" select="."/> 
         <xsl:with-param name="title"> 
          <xsl:value-of select="$book_title"/> 
         </xsl:with-param> 
        </xsl:call-template> 
       </xsl:result-document> 
      </xsl:for-each> 
     </xsl:template> 
    <xsl:template name="procB"> 
     <xsl:param name="context"/> 
     <xsl:param name="title"/> 
     <html > 
     <head> 
       <xsl:call-template name="header"> 
        <xsl:with-param name="title" select="$title"/> 
       </xsl:call-template> 
     </head> 
     <body> 
       <div id="root"> 
        <xsl:apply-templates select="."/> 
       </div> 
     </body> 
    </html> 
</xsl:template> 


</xsl:transform> 

そして、あなたはXHTML要素を生成することになって任意の追加モジュールを持っている場合、あなたがする必要がある場合は、モジュールのルート要素にxmlns="http://www.w3.org/1999/xhtml"を置くかを確認してくださいしたいと思います他の名前空間に要素を作成し、XHTMLを出力するテンプレートにも要素を作成します。

+0

提案してくれてありがとうございますが、私は '' xsl:transform [@ xmlns = 'http://www.w3.org/1999/xhtml'] ''を入れようとしました。 – Cylian

+0

ええ、はい、あなたの設定は一時的な要素(すなわち 'cylianz'要素)を作成すると複雑になります。おそらくこれはおそらく –

+0

私はあなたの意見が絶対に正しいことを認めなければならないと思うし、いくつかのハードルの後で私は空の名前空間を酷使することができた。 '' xsl:transform [@ xmlns = 'http://www.w3.org/ 1999/xhtml '] ''を実行し、続いて '' xmlns''を '' cylianz» ''の中に適用します。問題は解決されました。 – Cylian

3

出力には「迷惑な」名前空間宣言の2種類があります:冗長ノイズ(使用されていない名前空間接頭辞が宣言されているため)が必要な宣言と、宣言が不要な宣言意図された名前空間とは異なる名前空間の要素

最初のケースでは、XSLTはexclude-result-prefixesやcopy-namespaces = 'no'などの機能を提供してノイズを取り除きます。

2番目のケース(私が思うところです)では、ネームスペースの宣言は、スタイルシートの作成者が間違ったネームスペースの要素を最初に作成したという兆候です。解決策は、要素を作成したコード、およびそれを修正します。たとえば、<foo xmlns="something"/>を別の名前空間で作成する予定のときに、名前空間に要素を作成しないリテラル結果要素<foo>を記述したとします。

+0

@マルティン:助けてくれてありがとう、しかし、私はすでにあなたが言ったように、トリックを試みたが、適切な結果を得ていない。 – Cylian

+0

@Dr。ケイ:貴重で正確な提案をありがとう。私はそれが何とか私に希望の出力を得る方向を示していると思う。 – Cylian

3

のは、このXMLドキュメントてみましょう。ここでは

<x:t xmlns:x="some:x"> 
<a/> 
<b/> 
</x:t> 

を、おそらくあなたのようなコードです:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

    <xsl:template match="/*"> 
     <t xmlns="some:x"> 
     <xsl:copy-of select="*" copy-namespaces="no"/> 
     </t> 
    </xsl:template> 
</xsl:stylesheet> 

は、それは、この不要な結果生成:

<t xmlns="some:x"> 
    <a xmlns=""/> 
    <b xmlns=""/> 
</t> 

この結果はなぜ生成されますか?

あなたは「現状のまま」の要素は、彼らがしている名前空間を変更しないようにノードは、コピーされます。属性copy-namespaces="no"はこれだけの要素に属する名前空間ノードがコピーからスキップされることを指定し<xsl:copy-of>を使用しているため要素が独自の名前空間を変更するわけではありません。

ソリューション

私たちがする「名前空間なし」から、この場合の要素が入っている名前空間を(変更したい。「一部:x」は、私たちは、この要素ノードをコピーするべきではありません

代わりに、私たちはこの1つの新しい要素を作成し、新しい要素があるべきで新しい名前空間を指定する必要があります。この変換は、同じXML DOCUMEに適用されると

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

    <xsl:template match="/*"> 
     <t xmlns="some:x"> 
     <xsl:apply-templates select="*"/> 
     </t> 
    </xsl:template> 

    <xsl:template match="*"> 
     <xsl:element name="{local-name()}" namespace="some:x"> 
     <xsl:apply-templates select="node() | @*"/> 
     </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

を指名手配、正しい結果がを生産しているNT(上記)、://www.w3:

<t xmlns="some:x"> 
    <a/> 
    <b/> 
</t> 
+0

助けてくれてありがとう。私は非常に限られた情報で質問をして申し訳ありません、すべての尊敬プログラマーに申し訳ありません。さて、私はもう一度投稿を編集して、より多くの洞察を提供しました。しかし、あなたの推測(ディミトレ氏)は何とか正しいです。助けてくれてありがとうが、私の問題は何とか違う。 – Cylian

+0

@Cylian:いくつかのコードを提供することは正しい方向への一歩です。 *完全な*コードとXMLの例を提供することができれば、短くて簡単なので、人々がそれを実行して再現できるようになるとさらに良いでしょう。現在提供されているコードの抜粋(ソースXML文書はありません)では、これは不可能です。私はあなたが適切にあなたの部分を行う場合に役立つ喜んでです。 –

+0

注:これは1.0ではなく、XSLT v2.0でのみ機能します。 – silkfire

関連する問題