2012-03-05 15 views
2

私はXMLのテキストを置き換える、よりシンプルで洗練された方法を探しています。ソースXMLのような場合:シンプルなXSLTテキストの置換

<A> 
<B> 
    <Name>ThisOne</Name> 
    <Target>abc</Target> 
</B> 
<B> 
    <Name>NotThisOne</Name> 
    <Target>abc</Target> 
</B> 
<B> 
    <Name>ThisOne</Name> 
    <Target>def</Target> 
</B> 
</A> 

私は「XYZ」に「ThisOne」の名前を持つすべてのターゲット要素のテキストを変更したいです。

結果は次のようになります。私は、これは< XSLで行うことができることを考えていた

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="B/Target"> 
    <xsl:choose> 
     <xsl:when test="../Name/text()='ThisOne'"><Target>xyz</Target></xsl:when> 
     <xsl:otherwise><Target><xsl:value-of select="text()"/></Target></xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

:テンプレートマッチ= "B /ターゲット/テキスト()

<A> 
<B> 
    <Name>ThisOne</Name> 
    <Target>xyz</Target>  <-- Changed. 
</B> 
<B> 
    <Name>NotThisOne</Name> 
    <Target>abc</Target> 
</B> 
<B> 
    <Name>ThisOne</Name> 
    <Target>xyz</Target>  <-- Changed. 
</B> 
</A> 

私はこれを達成">だから、要素全体ではなくテキストだけを置き換えることができましたが、残りの部分はわかりませんでした。

ありがとうございます。

+0

興味深い - 3分で非常に似た3つの答え - 私は本当にここで実際の専門家の一人と文体の比較とコントラストを歓迎します。 *特に、*私のソリューションの改善を指摘した場合 – Kevan

+1

@Kevan - あなたの答えの唯一の問題は、 ''要素に属性が含まれていた場合、その属性が取り除かれることです。 –

+0

@DevNull - 良い点 - あなたの/ text()スタイルは、入力文書が変更され、ターゲット要素に属性を持つことが予期しない動作をする可能性は低い - 私は尋ねてうれしいよ:) – Kevan

答えて

5

このスタイルシート:あなたのXML入力を使用して

<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="B[Name='ThisOne']/Target/text()"> 
    <xsl:text>xyz</xsl:text> 
    </xsl:template> 

</xsl:stylesheet> 

は生成します。

<A> 
    <B> 
    <Name>ThisOne</Name> 
    <Target>xyz</Target> 
    </B> 
    <B> 
    <Name>NotThisOne</Name> 
    <Target>abc</Target> 
    </B> 
    <B> 
    <Name>ThisOne</Name> 
    <Target>xyz</Target> 
    </B> 
</A> 
+0

ありがとう、ありがとう! – uncaged

+0

+1良い答えです。優秀なXSLTコードの場合は –

+0

+1です。 –

1

これは、あなたがしなければならないのです。

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

<xsl:template match="B/Target[../Name='ThisOne']"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*"/> 
    <xsl:text>xyz</xsl:text> 
    </xsl:copy> 
</xsl:template> 

最初のテンプレートは、「恒等変換であります入力をそのまま出力にコピーします。 2番目は変更したい特定のターゲットと一致し、タグと属性をコピーして、目的のテキストを置き換えます。

+0

ニース、ありがとう! – uncaged

1
<?xml version="1.0" encoding="iso-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cds="cds_dt" exclude-result-prefixes="cds"> 
    <!-- Identity transfrom - just copy what doesn't need changing --> 
    <xsl:template match="@* | node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* | node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <!-- a rule for what does need changing --> 
    <!-- Change all Target nodes whose parent has a child of Name equal to ThisOne --> 
    <xsl:template match="/A/B[Name='ThisOne']/Target"> 
     <Target>xyz</Target> 
    </xsl:template> 
</xsl:stylesheet> 
+0

ありがとうございます。これは確かにきれいですが、テキストだけでなく、要素全体を置き換える必要はありません。 – uncaged

関連する問題