2017-08-04 15 views
0

私は以下のような複数のノードを持つXMLを持っています。私は各ノードをループして、他のノードにwd:day_of_weekと同じものがあるかどうかを確認してから、一致したすべての値に対してすべてwd:calculated_quatityを追加する必要があります。各ノードの要素を比較する方法と各ループのxslで同じ場合の合計値

たとえば、以下のxmlの場合、「月曜日」として2つの値があります。これらの2つのうちwd:calculated_quantity4.75 + 4.08333として追加する必要があります。

XML:

<wd:Time_Blocks_for_Worker> 
      <wd:Day_of_the_Week>Monday</wd:Day_of_the_Week> 
      <wd:Calendar_Date>2017-07-10-07:00</wd:Calendar_Date> 
      <wd:Time_Type wd:Descriptor="Hours Worked"> 
       <wd:ID wd:type="WID">da128ce5a1dc103f5656dad4dad70868</wd:ID> 
       <wd:ID wd:type="Time_Code_Reference_ID">CA Hours Worked In/Out</wd:ID> 
      </wd:Time_Type> 
      <wd:Calculated_Quantity>4.75</wd:Calculated_Quantity> 
     </wd:Time_Blocks_for_Worker> 
     <wd:Time_Blocks_for_Worker> 
      <wd:Day_of_the_Week>Monday</wd:Day_of_the_Week> 
      <wd:Calendar_Date>2017-07-10-07:00</wd:Calendar_Date> 
      <wd:Time_Type wd:Descriptor="Hours Worked"> 
       <wd:ID wd:type="WID">da128ce5a1dc103f5656dad4dad70868</wd:ID> 
       <wd:ID wd:type="Time_Code_Reference_ID">CA Hours Worked In/Out</wd:ID> 
      </wd:Time_Type> 
      <wd:Calculated_Quantity>4.083333</wd:Calculated_Quantity> 
     </wd:Time_Blocks_for_Worker> 
     <wd:Time_Blocks_for_Worker> 
      <wd:Day_of_the_Week>Tuesday</wd:Day_of_the_Week> 
      <wd:Calendar_Date>2017-07-11-07:00</wd:Calendar_Date> 
      <wd:Time_Type wd:Descriptor="Hours Worked"> 
       <wd:ID wd:type="WID">da128ce5a1dc103f5656dad4dad70868</wd:ID> 
       <wd:ID wd:type="Time_Code_Reference_ID">CA Hours Worked In/Out</wd:ID> 
      </wd:Time_Type> 
      <wd:Calculated_Quantity>4.75</wd:Calculated_Quantity> 
     </wd:Time_Blocks_for_Worker> 
     <wd:Time_Blocks_for_Worker> 
      <wd:Day_of_the_Week>Tuesday</wd:Day_of_the_Week> 
      <wd:Calendar_Date>2017-07-11-07:00</wd:Calendar_Date> 
      <wd:Time_Type wd:Descriptor="Hours Worked"> 
       <wd:ID wd:type="WID">da128ce5a1dc103f5656dad4dad70868</wd:ID> 
       <wd:ID wd:type="Time_Code_Reference_ID">CA Hours Worked In/Out</wd:ID> 
      </wd:Time_Type> 
      <wd:Calculated_Quantity>4.5</wd:Calculated_Quantity> 
     </wd:Time_Blocks_for_Worker> 

私はをループに以下のようにXSLをしようとして比較しています。

<Calculated_Quantity> 
      <xsl:for-each select="wd:Time_Blocks_for_Worker"> 
      <xsl:choose> 
       <xsl:if test="translate(wd:Day_of_the_Week, $smallcase, $uppercase) = wd:Day_of_the_Week"> 
       <xsl:when test="wd:Day_of_the_Week = wd:Day_of_the_Week"> 
       <xsl:value-of 
              select="sum(wd:Time_Blocks_for_Worker/wd:Calculated_Quantity_1 | wd:Time_Blocks_for_Worker/wd:Calculated_Quantity)"/> 
       </xsl:when> 
      </xsl:choose> 
      </xsl:for-each>  
     </Calculated_Quantity> 
+0

これは*グループ化の質問です。検索を行う - おそらく最も頻繁に質問されるXSLTの質問です。 XSLT 1.0または2.0では答えが異なることに注意してください。 –

答えて

0

StackOverflowの上のXSLTタグの下をグループ化の詳細な説明と例がたくさんあります。変換に使用されているXSLTのバージョンに基づいて、XSLT 1.0とXSLT 2.0では答えが異なります。

質問で提供されたサンプルXMLは、名前空間接頭辞wd:を削除した後に変換に使用されています。 グループ化の使用を実証するためのサンプル出力が生成されています。

XSLT 1.0

<xsl:key>次に定義されたキーに類似しているテンプレートと一致

<xsl:key name="weekday" match="Time_Blocks_for_Worker" use="Day_of_the_Week" /> 

をグループ化するために定義されなければなりません。

<xsl:template match="Time_Blocks_for_Worker[generate-id() = generate-id(key('weekday', Day_of_the_Week)[1])]"> 

次に、一致した要素の子ノードにアクセスし、要件に従って使用することができます。以下は、平日に働いた時間の合計を計算するサンプル出力を生成するXSLTです。

<xsl:stylesheet exclude-result-prefixes="xsl" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:key name="weekday" match="Time_Blocks_for_Worker" use="Day_of_the_Week" /> 
    <xsl:template match="Time_Blocks_for_Worker[generate-id() = generate-id(key('weekday', Day_of_the_Week)[1])]"> 
     <xsl:variable name="timeBlock" select="key('weekday', Day_of_the_Week)" /> 
     <WeekDay> 
      <Name> 
       <xsl:value-of select="$timeBlock/Day_of_the_Week" /> 
      </Name> 
      <Hours> 
       <xsl:value-of select="sum($timeBlock/Calculated_Quantity)" /> 
      </Hours> 
     </WeekDay> 
    </xsl:template> 
    <xsl:template match="Time_Blocks_for_Worker[not(generate-id() = generate-id(key('weekday',Day_of_the_Week)[1]))]" /> 
</xsl:stylesheet> 

このXSLTは、サンプル出力を生成

以下
<WeekDay> 
    <Name>Monday</Name> 
    <Hours>8.833333</Hours> 
</WeekDay> 
<WeekDay> 
    <Name>Tuesday</Name> 
    <Hours>9.25</Hours> 
</WeekDay> 

XSLT 2.0

XSLT 2.0 <xsl:for-each-group>機能を提供することによってグループ化するための簡単かつコンパクトなソリューションを提供します。

<xsl:stylesheet exclude-result-prefixes="xsl" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:template match="/*"> 
     <xsl:for-each-group select="Time_Blocks_for_Worker" group-by="Day_of_the_Week"> 
      <WeekDay> 
       <Name> 
        <xsl:value-of select="current-grouping-key()" /> 
       </Name> 
       <Hours> 
        <xsl:value-of select="sum(current-group()/Calculated_Quantity)" /> 
       </Hours> 
      </WeekDay> 
     </xsl:for-each-group> 
    </xsl:template> 
</xsl:stylesheet> 

このXSLT 2.0も、XSLT 1.0と同じサンプル出力を生成します。

関連する問題