3

Microsoft の XSLT プロセッサを使用しています (1.0 のみ)

XML の開始行:

<?xml version="1.0" encoding="utf-8"?>
<Header xmlns="http:\\OldNameSpace.com">
    <Detail>

次の XSLT テンプレートを使用して<Header>、ドキュメントの要素を取得し、その名前空間を変更します。

<xsl:template match="*">
    <xsl:element name="{name()}" xmlns="http:\\NewNameSpace.com"> 
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates />
    </xsl:element>
</xsl:template>

<Header xmlns="http:\\OldNameSpace.com">に変わる<Header xmlns="http:\\NewNameSpace.com">

ただし、次の出力が得られるように、これに 2 番目の名前空間を追加する必要があります。

<Header xmlns="NewNameSpace.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

私は使用してみました:

<xsl:template match="*">
    <xsl:element name="{name()}" xmlns="NewNameSpace.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates />
    </xsl:element>
</xsl:template>

ただし、元の XSLT テンプレートと同じ出力しか得られません。

これがなぜなのか、誰かが私に教えてもらえますか?

4

3 に答える 3

5

この変換:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:old="http:\\OldNameSpace.com"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  exclude-result-prefixes="old xsi">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pNewNamespace" select="'http:\\NewNameSpace.com'"/>

 <xsl:variable name="vXsi" select="document('')/*/namespace::*[name()='xsi']"/>

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

    <xsl:template match="old:*">
        <xsl:element name="{local-name()}" namespace="{$pNewNamespace}">
          <xsl:copy-of select="$vXsi"/>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates />
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

次の XML ドキュメントに適用した場合:

<Header xmlns="http:\\OldNameSpace.com">
    <Detail/>
</Header>

必要な正しい結果を生成します(私が推測することです)

<Header xmlns="http:\\NewNameSpace.com"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <Detail/>
</Header>
于 2012-04-11T12:14:26.890 に答える
2

xsl:element (リテラルの結果要素とは異なり) は、スコープ内のすべての名前空間を結果にコピーするのではなく、要素名に必要な名前空間のみを、その名前から暗黙的に、または名前空間引数で指定されたとおりにコピーします)。

xslt2 はこの場合に xsl:namespace 命令を追加しますが、xslt1 で行う最も簡単な方法は次のとおりです。

どこ

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

祖先のどこか (xsl:stylesheet など)。

これにより、出力にスプリアスが追加xsi:tmp=""されますが、名前空間宣言も追加されます。実際にこの名前空間に属性が必要な場合は、たとえばxsi:type、上記の tmp の代わりにそれを使用すれば完了です。xsi 名前空間の余分な、おそらく無効な属性を気にしない場合は、完了です。それ以外の場合は、変数で上記を実行してから、 を使用msxsl:node-setして変数にクエリを実行し、偽の余分な属性を削除します。

于 2012-04-11T08:59:07.750 に答える
2

生成したい名前空間が静的にわかっている場合、XSLT 1.0 でそれを行う最も簡単な方法は、xsl:copy-of を使用することです。ソース ドキュメントを作成し、の呼び出し内で<dummy xmlns:xsi="http://whatever"/>実行します。<xsl:copy-of select="document('dummy.xml')/*/namespace::xsi"/>xsl:element

于 2012-04-11T11:37:44.473 に答える