2017-02-16 17 views
1

私は反復プログラミングからXSLTへの飛躍に苦労しています。私はここに一つ前の質問をしましたが、それはかなり助けになりましたが、今は別の質問に戻ります。XSLTグループ化の問題

XSLT 1.0を使用しているシステムのオーダーインポートファイルを生成しようとしています。私はちょうど注文IDを見たいと、「はい」または「いいえ」、応じて出力するためにその後

<orders> 
    <order> 
    <id>1</id> 
    <items> 
     <item> 
      <sku>12345</sku> 
      <addon></addon> 
     </item> 
     <item> 
      <sku>23456</sku> 
      <addon>A</addon> 
     </item> 
     <item> 
      <sku>34567</sku> 
      <addon>B</addon> 
     </item> 
    </items> 
    </order> 
    <order> 
    <id>2</id> 
    <items> 
     <item> 
      <sku>12345</sku> 
      <addon></addon> 
     </item> 
     <item> 
      <sku>23456</sku> 
      <addon></addon> 
     </item> 
    </items> 
    </order> 
</orders> 

、以下の例のソースデータを思い付いたいくつかのロジックを実行する必要があり、そしてそれを簡素化しますそのオーダに含まれるアイテムがアドオン用に定義された値を持つかどうか。私はその値が何であれ気にしませんが、それが何かの項目に空白以外の場合は、出力をyesにして、すべての項目がアドオンのために空白であれば、出力はその注文に対してnoを表示します。上記のサンプルデータでは、出力は何かで単に

1 Yes 
2 No 

最初の推測は私が完全にキーの構文を理解していないと、それはより多くのコピーだと認めるよ

<xsl:key name="opt" match="item/addon" use="concat(ancestor::orders/order/id, '|', .)" /> 

<xsl:template match="/"> 
    <xsl:for-each select="orders/order"> 
     <xsl:value-of select="id" /> 
     <xsl:for-each select="orders/order/item/addon[count(. | key('opt', concat(orders/order/id), '|', .))[1]) = 1]"> 
     <xsl:choose> 
      <xsl:when test=".=''"><xsl:text>Yes</xsl:text></xsl:when>   
      <xsl:otherwise><xsl:text>No</xsl:text></xsl:otherwise> 
     </xsl:choose> 
     </xsl:for-each> 
    </xsl:for-each> 
</xsl:template> 

たする必要があります/私が自分自身を思い付くことができた何よりもペースト。私の試みを見てみると、#1の注文ではアドオンが異なる値を持つので、これはYesを2回出力すると思います。

私は理解してプログラミング言語でこれをやっていた場合、私は私が知っているので、私はXSLTで使用可能なものに擬似コードを変換するために苦労しています。この擬似コード

bool hasAddon = false; 
foreach(item in items) 
{ 
    if(item.addon != "") 
    { 
     hasAddon = true; 
     break; 
    } 
} 
if(hasAddon) 
    output Yes 
else 
    output No 

のようなものを使用したいですfor-eachはXSLTでは全く同じではないので、for-eachを壊すことはできず、変数の値は一度しか設定できません。これらのオプションがなければ、私は失われてしまっていると思いますし、キーと再帰的なテンプレートを理解するのに問題があり、自分で解決策を見つけることができます。任意の助けが素晴らしいだろう

+0

あなたの商品は既にグループ化されています。グループに基準を満たす項目が含まれているかどうかを確認するだけです。このためにループや再帰は必要ありません。 –

答えて

3

私はあなたがキーが必要なのか分からない、あなたは単に<xsl:choose><xsl:when test="items/item/addon[normalize-space()]">Yes</xsl:when><xsl:otherwise>No</xsl:otherwise></xsl:choose>をチェックすることができます。 <xsl:for-each select="orders/order">の内部にあります。

+0

私は自分のアイテムとそのアドオンをグループ化する必要があると思っていたので、そのフィールドにできるさまざまな値に基づいて複数回報告する必要はありませんでした。私が言ったように、ここではアマチュア全員。 item/addon [normalize-space()]が参照しているものについて説明できますか?それは疑問ではありませんが、私はそれが何をしているのか理解したいと思います。特定のフィールドの値の汎用チェックを行うために必要なことがすべてあれば、それはうまくいくはずです。 – rsly

+1

@DanielHaley、訂正のおかげで、私はコードスニペットを編集しました。 –

+1

''の中で、 'order'要素はコンテキストノードであり、' (ダニエル・ヘイリーが指摘している訂正で)空白以外のテキスト・コンテンツを持つ' addon'子孫があるかどうかを調べるので、命令的なアプローチでループを使って何をしたいかを1つの式で調べます。 XPathでは、ノードを選択する式が、 'xsl:if/when test'のようなブール・コンテキストで使用されるとき、パスによって少なくとも1つのノードが選択されていると評価され、選択されたノードセットが空の場合にはfalseになります –