2011-07-11 14 views
2

に分割する:XSLTは、すべてのノード上でコピーして、私は次のXSLTん探している区切り

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <foo1>bar1</foo1> 
    <foo2>bar2^bar3^bar4</foo2> 
    <foo3>bar3^bar3</foo3> 
    <unknown>more data</unknown> 
</root> 

私がコピーしたい:例えば、の入力XMLを

すべての既存のノードを結果のXMLに追加します。私はすべてのノードが何であるかを知らないでしょう。すなわち、foo1ノードを受け取っていることを知らないでしょう。私はちょうどそれらを直接コピーしたいと思います。しかし、特定のノードについては、私はそれらが何であるかを知っているので、区切り文字で区切り、それに応じて番号を付けたいと思います。

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <foo1>bar1</foo1> 
    <foo2> 
     <foo2-1>bar2</foo2-1> 
     <foo2-2>bar3</food2-2> 
     <foo2-3>bar4</foo2-3> 
    </foo2> 
    <foo3> 
     <foo3-1>bar3</foo3-1> 
     <foo3-2>bar3</food2-2> 
    </foo3> 
    <unknown>more data</unknown> 
</root> 

ご協力いただければ幸いです。

ありがとうございました。

答えて

3

これは、XSLT 2.0で行うのは非常に簡単です:

XSLT 1.0で
<?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"/> 

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

<xsl:template match="text()[contains(.,'^')]"> 
    <xsl:variable name="elementName" select="name(..)"/> 
    <xsl:for-each select="tokenize(.,'\^')"> 
     <xsl:element name="{$elementName}-{position()}"> 
      <xsl:value-of select="."/> 
     </xsl:element> 
    </xsl:for-each> 
</xsl:template> 

</xsl:stylesheet> 

あなたは再帰的なテンプレートの呼び出しを使用する必要があります。例:

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

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

<xsl:template match="text()[contains(.,'^')]"> 
    <xsl:variable name="elementName" select="name(..)"/> 

    <xsl:call-template name="splitIntoElements"> 
     <xsl:with-param name="baseName" select="name(..)" /> 
     <xsl:with-param name="txt" select="." />  
    </xsl:call-template> 

</xsl:template> 

<xsl:template name="splitIntoElements"> 
    <xsl:param name="baseName" /> 
    <xsl:param name="txt" /> 
    <xsl:param name="delimiter" select="'^'" /> 
    <xsl:param name="index" select="1" /> 

    <xsl:variable name="first" select="substring-before($txt, $delimiter)" /> 
    <xsl:variable name="remaining" select="substring-after($txt, $delimiter)" /> 

    <xsl:element name="{$baseName}-{$index}"> 
     <xsl:choose> 
      <xsl:when test="$first"> 
       <xsl:value-of select="$first" /> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:value-of select="$txt" /> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:element> 

    <xsl:if test="$remaining"> 
     <xsl:call-template name="splitIntoElements"> 
      <xsl:with-param name="baseName" select="$baseName" /> 
      <xsl:with-param name="txt" select="$remaining" /> 
      <xsl:with-param name="index" select="$index+1" /> 
      <xsl:with-param name="delimiter" select="$delimiter" /> 
     </xsl:call-template> 
    </xsl:if> 
</xsl:template> 

</xsl:stylesheet> 
+0

優れた、魅力的なように働いています! – WayneH

+0

それを聞いてうれしいです。 1.0または2.0バージョンを使用しましたか? –

関連する問題