4

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

oXygen IDE のポップアップに次のようなメッセージが表示されます。

xsl:copy-of を使用すると、copy-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>

問題が何であるかを理解しやすくなることを願っています。すべての提案を歓迎します。前もって感謝します。

4

3 に答える 3

5

確かにあなたのコードを見る必要がありますが、例えばあなたが持っていると思います

<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 xmlns=""/>
</foo>

あなたが望む間

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

これを修正するには、xsl: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>

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

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

[2回目の編集] 欲しいと思います

<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 を出力することになっているテンプレートを配置してください。

于 2012-04-16T11:47:35.163 に答える
3

There are two kinds of "unwanted" namespace declarations that might appear in your output: declarations that are unwanted because they are redundant noise (they declare namespace prefixes that aren't used), and declarations that are unwanted because they put the elements in a different namespace from the one intended.

In the first case, XSLT provides features such as exclude-result-prefixes and copy-namespaces='no' to get rid of the noise.

In the second case (which is where I think you are), the namespace declarations are a symptom of the fact that the stylesheet author created the elements in the wrong namespace in the first place, and the solution is to look at the code that created the elements, and fix it. For example you might have written a literal result element <foo> that creates an element in no namespace, when you intended <foo xmlns="something"/> to create it in some other namespace.

于 2012-04-16T11:59:02.297 に答える
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>

なぜこのような結果が得られるのでしょうか?

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

解決策:

要素が含まれる名前空間を変更したい場合 (この場合、「名前空間なし」から「some:x」に変更する場合)、この要素ノードをコピーするべきではありません。

代わりに、この要素から新しい要素を作成し、新しい要素が存在する新しい名前空間を指定する必要があります。

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

この変換が同じ XML ドキュメント (上記) に適用されると、必要な正しい結果が生成されます。

<t xmlns="some:x">
   <a/>
   <b/>
</t>
于 2012-04-16T12:53:37.967 に答える