2012-04-14 1 views
1

私はSaxon HE 9-4-0-3Jを使用しています。私の目的は、xsl:apply-templatesselect属性を使用して各<RECORD>要素に対して反復処理を行いますが、xmlの単一の<RECORD>要素のみが処理されています。xsl:apply-templatesはselectによって与えられた各ノードを反復しません

XML

<ENVELOPE> 
<PRODUCT> 
    <HEAD><FLAG>No</FLAG></HEAD> 
    <BODY> 
     <RECORD><Value>9</Value></RECORD> 
     <RECORD><Value>10</Value></RECORD> 
     <MISC>9</MISC> 
    </BODY> 
</PRODUCT> 

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template match="/ENVELOPE"> 
<Interface> 
    <Data><xsl:apply-templates select="PRODUCT"/></Data> 
</Interface> 
</xsl:template> 

<xsl:template match="PRODUCT"> 
    <xsl:choose> 
     <xsl:when test="HEAD/FLAG='Yes'"> 
     <xsl:attribute name="Match">Affirmative</xsl:attribute> 
     <xsl:apply-templates select="BODY/RECORD" mode="affr"/> 
     </xsl:when> 
     <xsl:when test="HEAD/FLAG='No'"> 
     <xsl:attribute name="Match">Negative</xsl:attribute> 
     <xsl:apply-templates select="BODY/RECORD" mode="neg"/> 
     </xsl:when> 
    </xsl:choose> 
</xsl:template> 

<xsl:template match="RECORD" mode="affr"> 
    <xsl:attribute name="Value"><xsl:value-of select="Value"/></xsl:attribute> 
</xsl:template> 

<xsl:template match="RECORD" mode="neg"> 
    <xsl:attribute name="Value"><xsl:value-of select="Value"/></xsl:attribute> 
</xsl:template> 

</xsl:stylesheet> 

出力

<Interface> 
     <Data Match="Negative" Value="9"/> <!-- this line doesn't appear, I want it to --> 
     <Data Match="Negative" Value="10"/> 
</Interface> 

答えて

2

<DATA...>出力タグは、<ENVELOPE...>に一致すると生成されるため、これらの出力は1つしか存在しません。 <xsl:attribute>ディレクティブは、この出力タグに追加するだけで、後の値は以前のタグを上書きします。

によう明示的に、あなたが出力をしたいDATAタグを生成する必要があります。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0"> 

    <xsl:output method="xml" indent="yes"/> 
    <xsl:template match="/ENVELOPE"> 
    <Interface> 
     <xsl:apply-templates select="PRODUCT"/> 
    </Interface> 
    </xsl:template> 

    <xsl:template match="PRODUCT"> 
    <xsl:variable name="flag"> 
     <xsl:choose> 
     <xsl:when test="HEAD/FLAG='Yes'">Affirmative</xsl:when> 
     <xsl:when test="HEAD/FLAG='No'">Negative</xsl:when> 
     </xsl:choose> 
    </xsl:variable> 

    <xsl:apply-templates select="BODY/RECORD"> 
     <xsl:with-param name="flag"><xsl:value-of select="$flag"/></xsl:with-param> 
    </xsl:apply-templates> 

    </xsl:template> 

    <xsl:template match="RECORD"> 
    <xsl:param name="flag"/> 
    <Data Value="{Value}" Match="{$flag}"/> 
    </xsl:template> 

</xsl:stylesheet> 
+0

あなたの最初の段落は、私が間違っていた場所を理解する手助けをしてくれてありがとうございます。 –

2

問題は、あなたが同じ名前を持つ2つの属性を作成しているということである - Value。整形式のXML文書では、要素は同じ名前を持つ複数の属性を持つことはできません。結果列の属性Aが表示され、他の属性Bと同じ名前を持つ場合

9:W3C XSLT 2.0 Specificationを(これも、正確にXSLT 1.0で同じである)引用する

結果シーケンスの後半で、 属性Aが結果シーケンスから破棄されます。

したがって、同じ名前の複数の属性に対してXSLTが生成するたびに、最後の属性のみが出力にコピーされます。これが表示されます。ここ

は短く、単純な溶液(2つのだけテンプレート、無条件文、パラメータなし)ある:

<ENVELOPE> 
    <PRODUCT> 
     <HEAD> 
      <FLAG>No</FLAG> 
     </HEAD> 
     <BODY> 
      <RECORD> 
       <Value>9</Value> 
      </RECORD> 
      <RECORD> 
       <Value>10</Value> 
      </RECORD> 
      <MISC>9</MISC> 
     </BODY> 
    </PRODUCT> 
</ENVELOPE> 
:この変換が提供されるXML文書に適用され

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

<xsl:variable name="vDoc" select="/"/> 

<xsl:variable name="vMatch" select= 
"('Affirmative', 'Negative')[2 - number($vDoc/*/*/HEAD/FLAG eq 'Yes')]"/> 

<xsl:template match="/*"> 
    <Interface> 
    <xsl:apply-templates select="*/BODY/RECORD"/> 
    </Interface> 
</xsl:template> 

<xsl:template match="RECORD"> 
    <Data Match="{$vMatch}" Value="{Value}"/> 
</xsl:template> 
</xsl:stylesheet> 

希望の正しい結果が得られます

<Interface> 
    <Data Match="Negative" Value="9"/> 
    <Data Match="Negative" Value="10"/> 
</Interface> 
+0

Dimitreありがとうございました。私はStackOverflowであなたの答えを見て学びました。配列/変数の構造は強力です。 –

+0

@satishb:どうぞよろしくお願いいたします。 –

関連する問題