XSLT

2017-12-06 17 views
1

を使用してXML要素にセミコロンで文字列を分ける私がtransformatedているのxml:XSLT

<import> 
    <issue> 
     <article> 
      <languageVersion> 
       <title>some title</title> 
       <keywords>keyword1; keyword2; keyword3</keywords> 
      </languageVersion> 
     </article> 
     <article> 
      <languageVersion> 
       <title>some title</title> 
       <keywords>keyword1; keyword2; keyword3</keywords> 
      </languageVersion> 
     </article> 
    </issue> 
</import> 

そして今、私は、ターゲットXMLはこのようになるので、XSLT変換を使用して、セミコロンでタグ内のすべての単語を分けたい:

<import> 
    <issue> 
     <article> 
      <languageVersion> 
       <title>some title</title> 
       <keywords> 
        <keyword>keyword1</keyword> 
        <keyword>keyword2</keyword> 
        <keyword>keyword3</keyword> 
       </keywords> 
      </languageVersion> 
     </article> 
     <article> 
      <languageVersion> 
       <title>some title</title> 
       <keywords> 
        <keyword>keyword1</keyword> 
        <keyword>keyword2</keyword> 
        <keyword>keyword3</keyword> 
       </keywords> 
      </languageVersion> 
     </article> 
     <article> 
    </issue> 
</import> 

XSLT変換を使用してこれを行うにはどうすればよいですか?私はthereからのコードを使用して、すでにすでに試みたが、生憎のコードは、XML要素の残りの部分を破壊した

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 
    <xsl:template match="keywords"> 
     <keywords> 
      <xsl:apply-templates/> 
     </keywords> 
    </xsl:template> 
    <xsl:template match="keywords" name="split"> 
     <xsl:param name="pText" select="."/> 
     <xsl:param name="pItemElementName" select="'keyword'"/> 
     <xsl:if test="string-length($pText) > 0"> 
      <xsl:variable name="vNextItem" select= 
     "substring-before(concat($pText, ';'), ';')"/> 
      <xsl:element name="{$pItemElementName}"> 
       <xsl:value-of select="$vNextItem"/> 
      </xsl:element> 
      <xsl:call-template name="split"> 
       <xsl:with-param name="pText" select="substring-after($pText, ';')"/> 
       <xsl:with-param name="pItemElementName" select="$pItemElementName"/> 
      </xsl:call-template> 
     </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

答えて

3

をあなたは、彼らが同じ優先順位を持っている場合、XSLTでエラーと見なされkeywordsに一致する2つのテンプレートがあります。仕様によると...

XSLTプロセッサがエラーを通知することがあります。 エラーを通知しない場合は、一致するテンプレート のうち、スタイルシートで最後に発生するものを選択して回復する必要があります。

したがって、使用しているのは2番目のテンプレートだけです。

ただし、2番目のテンプレートの「一致」を削除して名前付きテンプレートにするだけで、最初のテンプレートを変更して名前付きテンプレートを直接呼び出すことができます。また、既存の要素の世話をするために、アイデンティティーテンプレートを追加する必要があり、その後、あなたの仕事は

このXSLTほぼ完璧に動作

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

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

    <xsl:template match="keywords"> 
     <xsl:copy> 
      <xsl:call-template name="split" /> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template name="split"> 
     <xsl:param name="pText" select="."/> 
     <xsl:param name="pItemElementName" select="'keyword'"/> 
     <xsl:if test="string-length($pText) > 0"> 
      <xsl:variable name="vNextItem" select= 
     "substring-before(concat($pText, ';'), ';')"/> 
      <xsl:element name="{$pItemElementName}"> 
       <xsl:value-of select="$vNextItem"/> 
      </xsl:element> 
      <xsl:call-template name="split"> 
       <xsl:with-param name="pText" select="substring-after($pText, ';')"/> 
       <xsl:with-param name="pItemElementName" select="$pItemElementName"/> 
      </xsl:call-template> 
     </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 
+0

を試してみてください行われますが、それは要素の間のノードを作成されていません私はそれを得るために何を変えるべきですか? – cerbin

+1

私はこれを行うために私の答えを改めました。 –

+0

これは優れています。私は答えを承認しました。これに加えて、どうにかしてすべてのキーワードから空白を削除することは可能ですか?だからキーワード2の代わりにキーワード2になります。 – cerbin