4

JDK Transformer (Oracle XML v2 Parser または JAXP) を使用した XSLT 変換中にパラメーターによって渡された値を使用して、結果の XML に xmlns 属性を追加しようとしていますが、常にデフォルトでhttp://www.w3.org/2000/xmlnsになります。 /

私のソース XML

<test/>

私の XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://example.com">
    <xsl:param name="myNameSpace" select="'http://neilghosh.com'"/>
    <xsl:template match="/">
        <process>
            <xsl:attribute name="xmlns:neil">
                <xsl:value-of select="$myNameSpace"/>
            </xsl:attribute>
        </process>
    </xsl:template>
</xsl:stylesheet>

私の結果

<?xml version="1.0"?>
<process xmlns="http://www.w3.org/2000/xmlns/" xmlns:neil="neilghosh.com">
</process>

私の望む結果

<?xml version="1.0"?>
<process xmlns="http://example.com"  xmlns:neil="neilghosh.com">
</process>
4

5 に答える 5

5

Michael Kay が正しい答えを提供してくれましたが、あなたのコメントに基づいて、それを変換に使用する方法がわかりません。

完全な変換は次のとおりです。

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:param name="pNamespace" select="'neilghosh.com'"/>

 <xsl:variable name="vDummy">
   <xsl:element name="neil:x" namespace="{$pNamespace}"/>
 </xsl:variable>

 <xsl:template match="/*">
  <xsl:element name="process" namespace="http://example.com">
    <xsl:copy-of select="namespace::*"/>
    <xsl:copy-of select="ext:node-set($vDummy)/*/namespace::*[.=$pNamespace]"/>
  </xsl:element>
 </xsl:template>
 </xsl:stylesheet>

この変換が提供された XML ドキュメントに適用されると、次のようになります。

<test/>

必要な正しい結果が生成されます。

<process xmlns="http://example.com" xmlns:neil="neilghosh.com" />
于 2012-08-29T16:26:51.260 に答える
5

まず、XSLT データ モデルでは、属性ノードを作成するのではなく、名前空間ノードを作成します。

通常、名前空間ノードは自動的に作成されます。特定の名前空間で要素または属性を作成すると、必要な名前空間ノード (したがって、シリアル化されると名前空間宣言) がプロセッサによって自動的に追加されます。

不要な名前空間ノードを作成する場合 (要素または属性の名前で使用されないため)、XSLT 2.0 では xsl:namespace を使用できます。XSLT 1.0 に行き詰まっている場合は、関連する名前空間に要素を作成してから、その名前空間ノードをコピーするという回避策があります。

<xsl:variable name="ns">
  <xsl:element name="neil:dummy" namespace="{$param}"/>
</xsl:variable>
<process>
  <xsl:copy-of select="$ns/*/namespace::neil"/>
</process>
于 2012-08-29T14:11:07.293 に答える
2

XML の名前空間宣言は、属性のように見えますが、属性ではありません。XSLT 2.0 では<xsl:namespace name="neil" select="$myNameSpace" />、名前空間宣言を結果ツリーに動的に追加するために使用できますが、その機能は XSLT 1.0 では使用できません。

于 2012-08-29T13:58:26.880 に答える
0

「xmlns」属性を自分で作成しようとしないでください。XSLT で名前空間を作成すると、自動的に作成されます。この XSLT は動作します (Saxon 9.4 でテスト済み):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:neil="neilghosh.com"    
xpath-default-namespace="http://example.com"
xmlns="http://example.com" version="2.0">

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:param name="myDynamicNamespace" select="'http://neilghosh.com'"/>

<xsl:template match="/">
    <xsl:element name="process">   
        <xsl:namespace name="neil" select="$myDynamicNamespace"/>
    </xsl:element>
</xsl:template>
</xsl:stylesheet>

次の出力が得られます。

<?xml version="1.0" encoding="UTF-8"?>
<process xmlns="http://example.com" xmlns:neil="http://neilghosh.com"/>
于 2012-08-29T13:44:24.293 に答える
0

最後に、XSLT プロセッサ (Oracle XML V2 パーサー) で動作する回避策を取得しました。

StreamResultに直接出力するのではなく、それを DOM ドキュメントに変換してから、その DOM をファイルシステムに永続化する必要がありました。

transform メソッドでDOMResultを使用しました

次の XSLT フラグメントは機能しましたが、余分な xmlns:xmlns="http://www.w3.org/2000/xmlns/" がありました。これはおそらくドキュメントに吸収され、ファイル システムに永続化したときに最終出力に表示されませんでした。

 <process>    
      <xsl:attribute name="xmlns">
        <xsl:value-of select="'http://example.com'"/>
      </xsl:attribute> 
 <process>

これが最善の方法ではないことはわかっていますが、解析の制約を考えると、これが現在私が持っている唯一の選択肢です。

于 2012-08-30T14:22:01.293 に答える