1

私は、XML データのほとんどのコンテンツを小さな変更で通過させるという一般的なタスクのために、XSLT ライブラリを作成しようとしています。

現在、インクルード ファイルは次のようになっています (pass-through.xslt)。

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

  <!-- change default behaviour to copying all attributes and nodes -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- copy element but add a child node -->
  <xsl:template name="append">
    <xsl:param name="element"/>
    <xsl:param name="appendage"/>
    <xsl:element name="{name($element)}">
      <xsl:copy-of select="$element/namespace::*"/>
      <xsl:copy-of select="$element/@*"/>
      <xsl:apply-templates select="$element/node()"/>
      <xsl:copy-of select="$appendage"/>
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

その後、それを含むスタイルシートを作成することができ、何度も繰り返す (スタイルシートを呼び出す) ことを心配する必要はありません。

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

  <xsl:include href="pass-through.xslt"/>

  <!-- only worry about the transform you want -->
  <xsl:template match="element-to-be-modified">
  ...
  </xsl:template>

</xsl:stylesheet>

ドキュメントに要素を追加するだけの場合は、「append」を呼び出します。

<xsl:stylesheet 

これは、追加する要素の名前空間を除いて機能します。ルート要素に名前空間を持つ XML ファイルがある場合、プレフィックスの名前空間バインディングがないと言ってチョークします。ルート要素の名前空間をライブラリに追加すれば問題ありませんが、使用するたびに変更しなければならない場合、ライブラリの目的が無効になります。

呼び出し元のスタイルシートに xmlns:ns="uri" を追加できれば幸いですが、名前空間宣言の範囲はそのスタイルシートにのみ拡張されるようです。「追加」テンプレートが含まれているスタイルシートには拡張されません。

変身できるようになりたい

<ns:root xmlns:ns="http://example/namespace">
  <ns:child>old child</ns:child>
</ns:root>

<ns:root xmlns:ns="http://example/namespace">
  <ns:child>old child</ns:child>
  <ns:child>new child!</ns:child>
</ns:root>

恒等変換ボイラープレートを毎回含める必要はありません。「追加」テンプレートの要素に namespace="{namespace-uri()}" を追加するなど、さまざまなことを試しましたが、追加された要素の名前空間プレフィックスを保持するものはないようです。

4

2 に答える 2

1

交換

<xsl:element name="{name($element)}">

<xsl:element name="{name($element)}" namespace="{namespace-uri($element)}">
于 2013-04-12T07:50:57.970 に答える
0

名前付きテンプレートを「追加」するときに、コピー/変更する要素に既に配置されている場合は、現在の要素をパラメーターとして渡す必要はありません。ここでxsl:copyを使用できます

 <xsl:template name="append">
    <xsl:param name="appendage"/>
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
      <xsl:copy-of select="$appendage"/>
    </xsl:copy>
 </xsl:template>

あなたの例では、次のように呼び出すだけです

<xsl:template match="ns:root">
   <xsl:call-template name="append">
       <xsl:with-param name="appendage"><ns:child>new child!</ns:child></xsl:with-param>
   </xsl:call-template>
</xsl:template>

xsl:copyを使用すると、要素がコピーされ、名前空間が保持されます。

于 2013-04-12T12:32:17.673 に答える