1

サクソン HE 9-4-0-3J を使用しています。私の意図は、selecton 属性を使用xsl:apply-templatesして各要素を反復処理することですが、xml 内の<RECORD>単一の要素のみが処理されています。<RECORD>

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>
4

2 に答える 2

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>
于 2012-04-14T03:33:02.600 に答える
2

問題は、同じ名前の 2 つの属性を作成していることです-- Value。整形式の XML ドキュメントでは、要素に同じ名前の複数の属性を含めることはできません。

W3C XSLT 2.0 仕様を引用するには (これは XSLT 1.0 でもまったく同じです):

9. 結果シーケンス内の属性 A が、結果シーケンスの後半に現れる別の属性 B と同じ名前を持つ場合、属性 A は結果シーケンスから破棄されます

したがって、XSLT が要素に対して同じ名前の複数の属性を生成する場合は常に、最後の属性のみが出力にコピーされます。これが表示される内容です。

これは短くて簡単な解決策です(2つのテンプレートのみ、条件なし、パラメーターなし)

<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>

この変換が提供された XML ドキュメントに適用されると、次のようになります。

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

必要な正しい結果が生成されます。

<Interface>
   <Data Match="Negative" Value="9"/>
   <Data Match="Negative" Value="10"/>
</Interface>
于 2012-04-14T03:40:39.743 に答える