2016-08-09 20 views
1

私はXSL-FOおよびXPATHを初めて使用しており、以下の要件を満たすことが難しいです。私の要件は、XMLとXSL-FOから以下のような結果を得ることです:XSLT:条件がネストされたループ

私はあなたがPO_DATA/LINES/LINES_ROW/情報とLINE_ARRIVAL_DATEから来るLine #Item DescriptionQuantityを見たよう

Line# Item Description Quantity LINE_ARRIVAL_DATE 
1  test PO print-1  15  30-AUG-2016 
2  test PO print-2  25  30-SEP-2016 

以下のような結果を表示する必要がありますPO_DATA/PURCHASEORDER/LINE_REF/PO_LINE_TYPE からのもので、それらが関連する唯一の方法はLINES_ROWPO_LINE_TYPE XMLの親でPO_LINE_IDです。
XSL-FO(以下)のそれぞれについて、2つのfor-eachを持っていると思っていましたが、それは助けにはならず、私はできません。 私がこの要件を達成できるかどうか、またこれをどのように達成できるか教えてください。

ありがとうございます。あなたはXSLT 1.0プロセッサ使用している場合、スタイルシートが動作する以下の

<PO_DATA> 
    <SEGMENT1>321178</SEGMENT1> 
    <LINES> 
     <LINES_ROW> 
      <LINE_NUM>1</LINE_NUM> 
      <ITEM_DESCRIPTION>test PO print-1</ITEM_DESCRIPTION> 
      <CANCEL_FLAG>N</CANCEL_FLAG> 
      <UNIT_MEAS_LOOKUP_CODE>EACH</UNIT_MEAS_LOOKUP_CODE> 
      <ORDER_TYPE_LOOKUP_CODE>QUANTITY</ORDER_TYPE_LOOKUP_CODE> 
      <UNIT_PRICE>25</UNIT_PRICE> 
      <QUANTITY>15</QUANTITY> 
      <PO_HEADER_ID>408363</PO_HEADER_ID> 
      <PO_LINE_ID>697709</PO_LINE_ID> 
     </LINES_ROW> 
     <LINES_ROW> 
      <LINE_NUM>2</LINE_NUM> 
      <ITEM_DESCRIPTION>test PO print-2</ITEM_DESCRIPTION> 
      <CANCEL_FLAG>N</CANCEL_FLAG> 
      <UNIT_MEAS_LOOKUP_CODE>EACH</UNIT_MEAS_LOOKUP_CODE> 
      <ORDER_TYPE_LOOKUP_CODE>QUANTITY</ORDER_TYPE_LOOKUP_CODE> 
      <UNIT_PRICE>25</UNIT_PRICE> 
      <QUANTITY>15</QUANTITY> 
      <PO_HEADER_ID>408363</PO_HEADER_ID> 
      <PO_LINE_ID>697710</PO_LINE_ID> 
     </LINES_ROW> 
    </LINES> 
    <PURCHASEORDER> 
      <PO_HEADER_ID>408363</PO_HEADER_ID> 
      <LINE_REF> 
       <POLINE_TYP> 
        <PO_LINE_ID>697709</PO_LINE_ID> 
        <LINE_ARRIVAL_DATE>30-AUG-2016</LINE_ARRIVAL_DATE> 
       </POLINE_TYP> 
       <POLINE_TYP> 
        <PO_LINE_ID>697710</PO_LINE_ID> 
        <LINE_ARRIVAL_DATE>30-SEP-2016</LINE_ARRIVAL_DATE> 
       </POLINE_TYP> 
      </LINE_REF>  
    </PURCHASEORDER> 
</PO_DATA> 

<xsl:template match="/"> 
    <html> 
    <body> 
    <h2>My PO Lines</h2> 
    <table border="1"> 
     <tr bgcolor="#9acd32"> 
     <th style="text-align:left">Line #</th> 
     <th style="text-align:left">Item Description</th> 
     <th style="text-align:left">spolineid</th>  
     <th style="text-align:left">cpolineid</th>  
     <th style="text-align:left">comparison</th>  
     </tr> 
     <xsl:for-each select="PO_DATA/LINES/LINES_ROW"> 
     <!--xsl:for-each select="PURCHASEORDER/LINE_REF"-->  
     <!--xsl:for-each select="PURCHASEORDER/LINE_REF/POLINE_TYP"-->   
     <tr> 
     <td><xsl:value-of select="LINE_NUM"/></td> 
     <td><xsl:value-of select="ITEM_DESCRIPTION"/></td> 
     <!--xsl:variable name="spolineid" select="string(PO_LINE_ID)"/>  
     <td><xsl:value-of select="$spolineid" /></td> 
     <xsl:variable name="cpolineid" select="string(../../PURCHASEORDER/LINE_REF/POLINE_TYP/PO_LINE_ID)"/>   
     <td><xsl:value-of select="$cpolineid" /></td> 
     <td><xsl:if test = "$spolineid = $cpolineid "> <xsl:value-of select="../../PURCHASEORDER/LINE_REF/POLINE_TYP/LINE_ARRIVAL_DATE"/></xsl:if></td--> 

     <td><xsl:for-each select="PO_DATA/PURCHASEORDER/LINE_REF/POLINE_TYP"> 
       <xsl:value-of select="LINE_ARRIVAL_DATE"/> 
       </xsl:for-each></td>   

     </tr> 
     </xsl:for-each> 
     <!--/xsl:for-each-->  
    </table> 
    </body> 
    </html> 
</xsl:template> 
</xsl:stylesheet> 

答えて

0

:キーとキー()ソリューション:あなたの参考のために

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"> 
    <xsl:template match="/"> 
     <html> 
      <body> 
       <h2>My PO Lines</h2> 
       <table border="1"> 
        <tr bgcolor="#9acd32"> 
         <th style="text-align:left">Line #</th> 
         <th style="text-align:left">Item Description</th> 
         <th style="text-align:left">Quantity</th>  
         <th style="text-align:left">LINE_ARRIVAL_DATE</th> 
        </tr> 
        <xsl:for-each select="PO_DATA/LINES/LINES_ROW"> 
         <tr> 
          <td><xsl:value-of select="LINE_NUM"/></td> 
          <td><xsl:value-of select="ITEM_DESCRIPTION"/></td> 
          <td><xsl:value-of select="QUANTITY"/></td> 
          <td> 
           <xsl:value-of select="(/PO_DATA/PURCHASEORDER/LINE_REF/POLINE_TYP[string(PO_LINE_ID) = string(current()/PO_LINE_ID)]/LINE_ARRIVAL_DATE)[1]"/> 
          </td>   
         </tr> 
        </xsl:for-each> 
       </table> 
      </body> 
     </html> 
    </xsl:template> 
</xsl:stylesheet> 

を私はよりエレガントなXSLを追加しました:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"> 
    <xsl:key name="LINE" match="/PO_DATA/PURCHASEORDER/LINE_REF/POLINE_TYP" use="PO_LINE_ID"/> 
    <xsl:template match="/"> 
     <html> 
      <body> 
       <h2>My PO Lines</h2> 
       <table border="1"> 
        <tr bgcolor="#9acd32"> 
         <th style="text-align:left">Line #</th> 
         <th style="text-align:left">Item Description</th> 
         <th style="text-align:left">Quantity</th>  
         <th style="text-align:left">LINE_ARRIVAL_DATE</th> 
        </tr> 
        <xsl:for-each select="PO_DATA/LINES/LINES_ROW"> 
         <tr> 
          <td><xsl:value-of select="LINE_NUM"/></td> 
          <td><xsl:value-of select="ITEM_DESCRIPTION"/></td> 
          <td><xsl:value-of select="QUANTITY"/></td> 
          <td> 
           <xsl:value-of select="(key('LINE',PO_LINE_ID)/LINE_ARRIVAL_DATE)[1]"/> 
          </td>   
         </tr> 
        </xsl:for-each> 
       </table> 
      </body> 
     </html> 
    </xsl:template> 
</xsl:stylesheet> 

2つ以上のXSLTスタイルシートは、XSLT 1.0プロセッサSaxon 6.5.5およびMSXMLを使用してテストされています。

+0

'POLINE_TYP'要素は(私たちが知っている)1つだけなので、' xsl:key/@ match'は単に 'match =" POLINE_TYP "'になります。 'POLINE_TYP/PO_LINE_ID'の値が一意であれば、' @ select'中の ''(...)[1] ''は必要ないでしょう。それは、おそらく不規則な入力であることをどのように防御的にしたいかということになります。 –

+0

はい、「要素は一意です」「一度正確に表示されます」などのユーザーから聞きました。しかし、私はXSLT 2.0で厳密な型宣言を使用します。私はXSLTプロセッサのランタイムエラーメッセージに、実際の入力データによってas = "element()"などの前提条件が壊れていることがよくあります。 – tmakita

+0

お返事ありがとうございました。それは本当に私の要求を達成するのに役立った。私が気づいたことの1つは、XML Notepadを使用して最初はこれを実行していましたが、eq関数がXML Notepadに存在せず、したがってそれを使用できないことに気付きました。それにもかかわらず、この要件はOracle E-Businessスイートで機能しました。 –

関連する問題