2017-06-02 11 views
1

xsl:copy(XSLT 1.0)の使い方についてはさまざまな回答がありましたが、文書全体をコピーするのにうまく動作する同じ<xsl:template match="@*|node()">を使用しているようです。サブツリーをコピーしてテンプレートを適用する特定のノードに一致するように苦労しています。XSLTの使い方特定のXMLサブツリーをコピーするにはどうすればいいですか?

<MyXML> 
    <a> 
    <b>c</b> 
    </a> 
    <d> 
    <e>f</e> 
    </d> 
    <g x="y"> 
    <foo bar="baz"> 
     <item name="aname">quux</item> 
     <item name="bname">xyzzy</item> 
    </foo> 
    </g> 
</MyXML> 

そして、このスタイルシート:このXMLドキュメント与え例えば

、私が何をしたいのですがどのような

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

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

    <xsl:template match="item[@name='bname']/text()"> 
    <xsl:value-of select="translate(current(), 'y', 'Y')" /> 
    </xsl:template> 

</xsl:stylesheet> 

は、その属性と子ノードと一緒にコピー唯一の要素fooです同時に、その翻訳「y」 - >「Y」を適用する。私はそれが<xsl:template match="//foo">または<xsl:template match="//foo/@*|//foo/node()"><xsl:template match="@*|node()">を変えるのと同じくらい簡単かもしれないと思った

<foo bar="baz"> 
    <item name="aname">quux</item> 
    <item name="bname">xYzzY</item> 
</foo> 

:私が望む結果がこれです。私はさまざまな順列を推測していますが、必要な結果を得ることはできません。

+1

アイデンティティテンプレート(xsl:copyを持つテンプレート)は、ドキュメント全体をコピーするだけでなく、投げるノードをコピーします。具体的には、「ノードをスローする」方法は、そのノードを選択するxsl:apply-templatesを実行することです。したがって、あなたが欠けているのは、ルートテンプレート( 'match ="/"')レベルで ''です。 –

答えて

2

だけfoo要素を処理したい場合、あなたは、単にルートノードと一致し、唯一のあなたは(したがって他のすべてを削除)したいノードにテンプレートを適用するテンプレートを追加することができます。

XSLT 1.0

それ以外の場合は結果は整形式のXML文書ではありません - これは、せいぜい1つの foo要素があるだろうと仮定していること
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

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

<xsl:template match="/"> 
    <xsl:apply-templates select="MyXML/g/foo"/> 
</xsl:template> 

<xsl:template match="item[@name='bname']/text()"> 
    <xsl:value-of select="translate(., 'y', 'Y')" /> 
</xsl:template> 

</xsl:stylesheet> 

注意。

+0

私はマッチングの仕組みを理解していないと思います - すべてのxsl:template宣言の暗黙の順序がありますか?どのように3つが一緒に働くかを説明する方法はありますか?私の直感は、各宣言がそれを上回る宣言と連続していると思いますが、これは間違っていますか? – Matt

+0

また、ルート( "/")レベルでのマッチで追加の宣言が必要な理由と、2つのxsl:template宣言だけではできない理由を理解できません。 – Matt

+2

@Mattデフォルトでは、[XSLT processing](https://www.w3.org/TR/xslt/#section-Processing-Model)はルートノードから始まり、スタイルシートが介入しない限り、そこから下に向かって進みます。あなたがそれらを無効にしない限り、適用される[組み込みテンプレートルール](https://www.w3.org/TR/xslt/#built-in-rule)もあります。この場合、 'b'と' e'のテキストノードが出力ツリーにコピーされることになります。 –

関連する問題