2

XSLTを使用せずに次の状況で使用する方法xsl:for-each-group

私の要件: Field1 .. Field6 の反復が Field1 .. グループ内の任意の反復の Field6 と一致する場合、金額を合計し、グループの最小 ID を取得する必要があります。

入力

<Shipment>
    <ID>1</ID>
    <Field1>abcd</Field1>
    <Field2>1234</Field2>
    <Field3>efgh</Field4>
    <Field4>5678</Field4>
    <Field5>ijkl</Field5>
    <Field6>90mn</Field6>
    <Amount>200.00</Amount>
</Shipment>
<Shipment>
    <ID>2</ID>
    <Field1>abcd</Field1>
    <Field2>1234</Field2>
    <Field3>efgh</Field4>
    <Field4>5678</Field4>
    <Field5>ijkl</Field5>
    <Field6>90mn</Field6>
    <Amount>600.00</Amount>
</Shipment>
<Shipment>
    <ID>3</ID>
    <Field1>1234</Field1>
    <Field2>abcd</Field2>
    <Field3>efgh</Field4>
    <Field4>5678</Field4>
    <Field5>2345</Field5>
    <Field6>80mn</Field6>
    <Amount>600.00</Amount>
</Shipment>

期待されるアウトプット

<Shipment>
    <ID>1</ID>  
    <Field1>abcd</Field1>
    <Field2>1234</Field2>
    <Field3>efgh</Field4>
    <Field4>5678</Field4>
    <Field5>ijkl</Field5>
    <Field6>90mn</Field6>
    <Amount>800.00</Amount> 
</Shipment>
<Shipment>
    <ID>2</ID>
    <Field1>1234</Field1>
    <Field2>abcd</Field2>
    <Field3>efgh</Field4>
    <Field4>5678</Field4>
    <Field5>2345</Field5>
    <Field6>80mn</Field6>
    <Amount>600.00</Amount>
</Shipment>
4

2 に答える 2

1

使用しないという要件はxsl:for-each-group、XSLT 2.0 プロセッサが利用できないことを明確に示しています

XSLT 1.0 ソリューションは次のとおりです。

<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:key name="kAllFields" match="Shipment" use=
 "concat(Field1,'+',Field2,'+',Field3,'+',Field4,'+',Field5,'+',Field6)"/>

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

 <xsl:template match=
  "Shipment
     [not(generate-id()
     =
      generate-id(key('kAllFields',
                      concat(Field1,'+',Field2,'+',Field3,'+',Field4,'+',Field5,'+',Field6))[1]))]
 "/>

 <xsl:template match="Shipment">
  <xsl:variable name="vGroup" select=
  "key('kAllFields', concat(Field1,'+',Field2,'+',Field3,'+',Field4,'+',Field5,'+',Field6))"/>

  <Shipment>
    <ID>
      <xsl:call-template name="min">
        <xsl:with-param name="pItems" select="$vGroup/ID"/>
      </xsl:call-template>
    </ID>
    <xsl:apply-templates select="*[starts-with(name(), 'Field')]"/>
    <Amount><xsl:value-of select="sum($vGroup/Amount)"/></Amount>
  </Shipment>
 </xsl:template>

 <xsl:template name="min">
  <xsl:param name="pItems" select="/.."/>
  <xsl:param name="pDataType" select="'number'"/>

  <xsl:for-each select="$pItems">
    <xsl:sort data-type="{$pDataType}"/>
    <xsl:if test="position() =1"><xsl:value-of select="."/></xsl:if>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

この変換が次の XML ドキュメント(提供された非常に不正な形式のフラグメント -- 修正され、整形式の XML ドキュメントにするために単一の最上位要素にラップされたもの) に適用される場合:

<t>
    <Shipment>
        <ID>1</ID>
        <Field1>abcd</Field1>
        <Field2>1234</Field2>
        <Field3>efgh</Field3>
        <Field4>5678</Field4>
        <Field5>ijkl</Field5>
        <Field6>90mn</Field6>
        <Amount>200.00</Amount>
    </Shipment>
    <Shipment>
        <ID>2</ID>
        <Field1>abcd</Field1>
        <Field2>1234</Field2>
        <Field3>efgh</Field3>
        <Field4>5678</Field4>
        <Field5>ijkl</Field5>
        <Field6>90mn</Field6>
        <Amount>600.00</Amount>
    </Shipment>
    <Shipment>
        <ID>3</ID>
        <Field1>1234</Field1>
        <Field2>abcd</Field2>
        <Field3>efgh</Field3>
        <Field4>5678</Field4>
        <Field5>2345</Field5>
        <Field6>80mn</Field6>
        <Amount>600.00</Amount>
    </Shipment>
</t>

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

<t>
   <Shipment>
      <ID>1</ID>
      <Field1>abcd</Field1>
      <Field2>1234</Field2>
      <Field3>efgh</Field3>
      <Field4>5678</Field4>
      <Field5>ijkl</Field5>
      <Field6>90mn</Field6>
      <Amount>800</Amount>
   </Shipment>
   <Shipment>
      <ID>3</ID>
      <Field1>1234</Field1>
      <Field2>abcd</Field2>
      <Field3>efgh</Field3>
      <Field4>5678</Field4>
      <Field5>2345</Field5>
      <Field6>80mn</Field6>
      <Amount>600</Amount>
   </Shipment>
</t>
于 2013-03-28T01:58:41.787 に答える
0

Field1 から Field6 で使用されていない区切り記号を選択する必要があります。

<xsl:param name="separator" select="'-'"/>
<xsl:template match="/shipments">
    <xsl:for-each-group select="Shipment" group-by="concat(Field1,$separator,Field2,$separator,Field3,$separator,Field4,$separator,Field5,$separator,Field6)">
        <xsl:copy-of select="current-group()[ID=min(current-group()/ID)]"/>
    </xsl:for-each-group>
</xsl:template>

作業

于 2013-03-27T22:56:59.077 に答える