4

次のような XSLT スタイルシートがあります。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                  xmlns:XQHeaderFunc="java:com.sonicsw.xq.service.xform.HeaderExtension"
                  xmlns:saxon="http://saxon.sf.net/">

  <saxon:script language="java" implements-prefix="XQHeaderFunc" src="java:com.sonicsw.xq.service.xform.HeaderExtension" />

  <xsl:output indent="yes" omit-xml-declaration="yes"/>

  <xsl:template match="/">
    <xsl:variable name="processId" select="XQHeaderFunc:getProperty(XQHeaderFunc:new(),'processId',-1)" />
    <xsl:value-of select="XQHeaderFunc:setProperty(XQHeaderFunc:new(),'processId',string(@id),-1)"/>

    <root>
      <xsl:apply-templates />
    </root>

  </xsl:template>

  <!-- Other stuff -->

</xsl:stylesheet>

2 番目の XSLT スタイルシートを使用してこのスタイルシートを変換し、XQHeaderFunc および saxon 名前空間に関係するものをすべて削除したいと考えています。これを行う方法はありますか?


要素を正常に処理する次のことを試しましたが、名前空間の宣言は消えたくないようです。

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:XQHeaderFunc="java:com.sonicsw.xq.service.xform.HeaderExtension"
                xmlns:saxon="http://saxon.sf.net/"
                exclude-result-prefixes="XQHeaderFunc saxon">

  <xsl:param name="XQHeaderReplacement" />
  <xsl:variable name="apos">'</xsl:variable>

  <!-- Copy all nodes -->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <!-- Remove saxon script tag -->
  <xsl:template match="saxon:script" />

  <!-- Remove elements with setProperty calls -->
  <xsl:template match="*[starts-with(@select, 'XQHeaderFunc:setProperty')]" />

  <!-- Replace getProperty calls with replacement value-->
  <xsl:template match="@select[starts-with(., 'XQHeaderFunc:getProperty')]">
      <xsl:attribute name="select">
        <xsl:value-of select="concat($apos, $XQHeaderReplacement, $apos)"/>
      </xsl:attribute>
    </xsl:template>
</xsl:stylesheet>

出力:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:XQHeaderFunc="java:com.sonicsw.xq.service.xform.HeaderExtension" 
                xmlns:saxon="http://saxon.sf.net/">

  <xsl:output indent="yes" omit-xml-declaration="yes" />

  <xsl:template match="/">
    <xsl:variable name="processId" select="''" />


    <root>
      <xsl:apply-templates />
    </root>

  </xsl:template>

  <!-- Other stuff -->

</xsl:stylesheet>
4

1 に答える 1

12

追加します

 exclude-result-prefixes="foo"

あなたの上に

 <xsl:stylesheet>

エレメント。foo次に、可能な場合、つまり、その名前空間に出力する要素または属性がない場合、の名前空間宣言は省略されます。

参考までに、この行の理由

<xsl:template match="xsl:stylesheet/@xmlns:foo" />`

xmlns:foo入力ドキュメントに属性がないため、エラーがスローされます。それは疑似属性です。一致パターンが一致を求めているのfooは、名前空間プレフィックスに対応する名前空間にあるという名前の属性xmlnsです。スタイルシートで名前空間プレフィックスを宣言していないxmlnsため、「プレフィックス xmlns が定義されていません」というエラーが発生します。

アップデート:

投稿された出力 (および私自身のテスト) からexclude-result-prefixes、名前空間宣言を削除するのに効果的ではなかったことがわかります。

1) まず、なぜそれが重要なのかを尋ねます。出力 XSLT の名前空間は変更されません。審美的な理由で削除しようとしているだけですか?

2) XSLT 1.0仕様を見ると、次のことに注意を払っていないように見え<xsl:copy>ますexclude-result-prefixes:

xsl:copy 要素をインスタンス化すると、現在のノードのコピーが作成されます。現在のノードの名前空間ノードも自動的にコピーされます...

AFAICT、リテラルの結果要素のみがベースの名前空間ノードを省略しますexclude-result-prefixes

<xsl:copy>それに基づいて、 IDテンプレート(要素用)を<xsl:element name="{name()}">またはその変形に置き換えてみます。その場合、非要素ノード用に個別の ID テンプレートが必要になります。

ID テンプレートを次の 2 つのテンプレートに置き換えました。

<!-- Copy elements -->
<xsl:template match="*" priority="-1">
   <xsl:element name="{name()}">
      <xsl:apply-templates select="node()|@*"/>
   </xsl:element>
</xsl:template>

<!-- Copy all other nodes -->
<xsl:template match="node()|@*" priority="-2">
   <xsl:copy />      
</xsl:template>

そしてそれは、無関係な ns 宣言なしで、望ましい出力であると私が信じているものを与えました:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
   <xsl:output indent="yes" omit-xml-declaration="yes" />

   <xsl:template match="/">
      <xsl:variable name="processId" select="''" />
      <root>
         <xsl:apply-templates />
      </root>
   </xsl:template>

   <!-- Other stuff -->
</xsl:stylesheet>

(わかりやすくするために空白を調整しました。)

于 2012-09-17T20:35:09.673 に答える