2

私はかなり厄介なHTMLソースコンテンツを扱っており、単一のolを(ソースからの)属性が特定のリストアイテムを独自のサブリストに入れるかどうかを決定するものに構造化しようとしています。リストもいくつかのolに分割されていますが、親ノードを無視することで回避できると思います。

ソース:

<div class="x-popup-text c3" id="POPUP172050488">
  <p>To add multiple balance adjustments:</p>
  <ol>
    <li class="kadov-p-CStep">
      <p class="Step">Check 
      <span class="hcp1">Add to queue</span> at the bottom of the page.</p>
    </li>
    <li class="kadov-p-CStep">
      <p class="Step">At the top of the page, enter the 
      <span class="hcp1">Account</span>. &#160;This is a three-part field:</p>
    </li>
    <li class="kadov-p-CStepBullet">
      <p class="StepBullet">In the first part, select the bank number &#160;from the drop-down list.</p>
    </li>
    <li class="kadov-p-CStepBullet">
      <p class="StepBullet">In the second part, select the application code from the drop-down list.</p>
    </li>
    <li class="kadov-p-CStepBullet">
      <p class="StepBullet">In the third part, enter the account number or click the account search button 
      <img src="../mag_glass_blue_bkgrd.gif" x-maintain-ratio="TRUE" width="16" height="16" border="0" class="hcp2 c1" /> to find it.</p>
    </li>
  </ol>
  <ol start="3">
    <li class="kadov-p-CStep">
      <p class="Step">Enter the start date for the adjustment in the 
      <span class="hcp1">From</span> field or click the calendar button 
      <img src="../calendar.gif" x-maintain-ratio="TRUE" width="16" height="18" border="0" class="hcp2 c2" /> to select the date.</p>
    </li>
    <li class="kadov-p-CStep">
      <p class="Step">Enter the end date for the adjustment in the 
      <span class="hcp1">Through</span> field or click the calendar button 
      <img src="../calendar.gif" x-maintain-ratio="TRUE" width="16" height="18" border="0" class="hcp2 c2" /> to select the date.</p>
    </li>
  </ol>
  <p class="StepText">
  <span class="hcp1">Tip:</span> &#160;The Through date must be the same as or after the From date.</p>
  <ol start="5">
    <li class="kadov-p-CStep">
      <p class="Step">For each balance you want to adjust, do the following:</p>
    </li>
    <li class="kadov-p-CStepBullet">
      <p class="StepBullet">In the table at the bottom of the page, find the appropriate 
      <span class="hcp1">Balance Type</span> for the adjustment.</p>
    </li>
    <li class="kadov-p-CStepBullet">
      <p class="StepBullet">Enter the 
      <span class="hcp1">Amount</span> of the adjustment to the right of the balance type.</p>
    </li>
    <li class="kadov-p-CStepBullet">
      <p class="StepBullet">If you want the adjustment to appear on the customer's statement, check the 
      <span class="hcp1">Print on Statements</span> checkbox that corresponds to the adjustment amount you entered.</p>
    </li>
  </ol>
  <ol start="6">
    <li class="kadov-p-CStep">
      <p class="Step">Click 
      <span class="hcp1">Add</span>.</p>
    </li>
    <li class="kadov-p-CStep">
      <p class="Step">Repeat steps 2 through 7 for each additional adjustment you want to add.</p>
    </li>
    <li class="kadov-p-CStep">
      <p class="Step">Click the 
      <span class="hcp1">View queue</span> link at the bottom of the page to enter the Work Queue and apply the adjustments.</p>
    </li>
  </ol>
</div>

私は知っている、それは混乱です。

したがって、基本的に:@ class ='kadov-p-CStep'を持つliは、第1レベルのliである必要があります。次の'kadov-p-Step'liの前に@class='kadov-p-CStepBullet'がある後続の兄弟liは、新しい親の下の従属リストに入れる必要があります。

ここの他の場所で、ノードセットの交差を選択するための式を見つけました。

$ns1[count(.|$ns2)=count($ns2)] 

私が自分自身の(おそらく非常に混乱した)方法で従おうとしたもの:

 <xsl:for-each select="following::li[contains(./@class,'CStepBullet')][count(.|following-sibling::li[not(contains(./@class,'Bullet'))][1]/preceding-sibling::li[contains(./@class,'CStepBullet')]) = count(following-sibling::li[not(contains(./@class,'Bullet'))][1]/preceding-sibling::li[contains(./@class,'CStepBullet')])] ">

現在、これは出力XMLに結果を生成しません。また、不必要に過剰に設計されていると確信しています。

ご覧いただきありがとうございます。事前にアドバイスをお寄せください。

4

2 に答える 2

1

I. この 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="kFollowing" match="li[@class='kadov-p-CStepBullet']"
  use="generate-id(preceding-sibling::li[@class='kadov-p-CStep'][1])"/>

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

 <xsl:template match="li[@class='kadov-p-CStep']">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>

    <xsl:variable name="vFollowing" select="key('kFollowing', generate-id())"/>

    <xsl:if test="$vFollowing">
      <ul>
        <xsl:apply-templates select="$vFollowing" mode="inGroup"/>
      </ul>
    </xsl:if>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="li[@class='kadov-p-CStepBullet']"/>

 <xsl:template match="li[@class='kadov-p-CStepBullet']" mode="inGroup">
  <xsl:call-template name="identity"/>
 </xsl:template>
 </xsl:stylesheet>

提供された XML ドキュメントに適用した場合:

<div class="x-popup-text c3" id="POPUP172050488">
  <p>To add multiple balance adjustments:</p>
  <ol>
    <li class="kadov-p-CStep">
      <p class="Step">Check
      <span class="hcp1">Add to queue</span> at the bottom of the page.</p>
    </li>
    <li class="kadov-p-CStep">
      <p class="Step">At the top of the page, enter the
      <span class="hcp1">Account</span>. &#160;This is a three-part field:</p>
    </li>
    <li class="kadov-p-CStepBullet">
      <p class="StepBullet">In the first part, select the bank number &#160;from the drop-down list.</p>
    </li>
    <li class="kadov-p-CStepBullet">
      <p class="StepBullet">In the second part, select the application code from the drop-down list.</p>
    </li>
    <li class="kadov-p-CStepBullet">
      <p class="StepBullet">In the third part, enter the account number or click the account search button
      <img src="../mag_glass_blue_bkgrd.gif" x-maintain-ratio="TRUE" width="16" height="16" border="0" class="hcp2 c1" /> to find it.</p>
    </li>
  </ol>
  <ol start="3">
    <li class="kadov-p-CStep">
      <p class="Step">Enter the start date for the adjustment in the
      <span class="hcp1">From</span> field or click the calendar button
      <img src="../calendar.gif" x-maintain-ratio="TRUE" width="16" height="18" border="0" class="hcp2 c2" /> to select the date.</p>
    </li>
    <li class="kadov-p-CStep">
      <p class="Step">Enter the end date for the adjustment in the
      <span class="hcp1">Through</span> field or click the calendar button
      <img src="../calendar.gif" x-maintain-ratio="TRUE" width="16" height="18" border="0" class="hcp2 c2" /> to select the date.</p>
    </li>
  </ol>
  <p class="StepText">
  <span class="hcp1">Tip:</span> &#160;The Through date must be the same as or after the From date.</p>
  <ol start="5">
    <li class="kadov-p-CStep">
      <p class="Step">For each balance you want to adjust, do the following:</p>
    </li>
    <li class="kadov-p-CStepBullet">
      <p class="StepBullet">In the table at the bottom of the page, find the appropriate
      <span class="hcp1">Balance Type</span> for the adjustment.</p>
    </li>
    <li class="kadov-p-CStepBullet">
      <p class="StepBullet">Enter the
      <span class="hcp1">Amount</span> of the adjustment to the right of the balance type.</p>
    </li>
    <li class="kadov-p-CStepBullet">
      <p class="StepBullet">If you want the adjustment to appear on the customer's statement, check the
      <span class="hcp1">Print on Statements</span> checkbox that corresponds to the adjustment amount you entered.</p>
    </li>
  </ol>
  <ol start="6">
    <li class="kadov-p-CStep">
      <p class="Step">Click
      <span class="hcp1">Add</span>.</p>
    </li>
    <li class="kadov-p-CStep">
      <p class="Step">Repeat steps 2 through 7 for each additional adjustment you want to add.</p>
    </li>
    <li class="kadov-p-CStep">
      <p class="Step">Click the
      <span class="hcp1">View queue</span> link at the bottom of the page to enter the Work Queue and apply the adjustments.</p>
    </li>
  </ol>
</div>

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

<div class="x-popup-text c3" id="POPUP172050488">
   <p>To add multiple balance adjustments:</p>
   <ol>
      <li class="kadov-p-CStep">
         <p class="Step">Check
      <span class="hcp1">Add to queue</span> at the bottom of the page.</p>
      </li>
      <li class="kadov-p-CStep">
         <p class="Step">At the top of the page, enter the
      <span class="hcp1">Account</span>.  This is a three-part field:</p>
         <ul>
            <li class="kadov-p-CStepBullet">
               <p class="StepBullet">In the first part, select the bank number  from the drop-down list.</p>
            </li>
            <li class="kadov-p-CStepBullet">
               <p class="StepBullet">In the second part, select the application code from the drop-down list.</p>
            </li>
            <li class="kadov-p-CStepBullet">
               <p class="StepBullet">In the third part, enter the account number or click the account search button
      <img src="../mag_glass_blue_bkgrd.gif" x-maintain-ratio="TRUE" width="16"
                       height="16"
                       border="0"
                       class="hcp2 c1"/> to find it.</p>
            </li>
         </ul>
      </li>
   </ol>
   <ol start="3">
      <li class="kadov-p-CStep">
         <p class="Step">Enter the start date for the adjustment in the
      <span class="hcp1">From</span> field or click the calendar button
      <img src="../calendar.gif" x-maintain-ratio="TRUE" width="16" height="18" border="0"
                 class="hcp2 c2"/> to select the date.</p>
      </li>
      <li class="kadov-p-CStep">
         <p class="Step">Enter the end date for the adjustment in the
      <span class="hcp1">Through</span> field or click the calendar button
      <img src="../calendar.gif" x-maintain-ratio="TRUE" width="16" height="18" border="0"
                 class="hcp2 c2"/> to select the date.</p>
      </li>
   </ol>
   <p class="StepText">
      <span class="hcp1">Tip:</span>  The Through date must be the same as or after the From date.</p>
   <ol start="5">
      <li class="kadov-p-CStep">
         <p class="Step">For each balance you want to adjust, do the following:</p>
         <ul>
            <li class="kadov-p-CStepBullet">
               <p class="StepBullet">In the table at the bottom of the page, find the appropriate
      <span class="hcp1">Balance Type</span> for the adjustment.</p>
            </li>
            <li class="kadov-p-CStepBullet">
               <p class="StepBullet">Enter the
      <span class="hcp1">Amount</span> of the adjustment to the right of the balance type.</p>
            </li>
            <li class="kadov-p-CStepBullet">
               <p class="StepBullet">If you want the adjustment to appear on the customer's statement, check the
      <span class="hcp1">Print on Statements</span> checkbox that corresponds to the adjustment amount you entered.</p>
            </li>
         </ul>
      </li>
   </ol>
   <ol start="6">
      <li class="kadov-p-CStep">
         <p class="Step">Click
      <span class="hcp1">Add</span>.</p>
      </li>
      <li class="kadov-p-CStep">
         <p class="Step">Repeat steps 2 through 7 for each additional adjustment you want to add.</p>
      </li>
      <li class="kadov-p-CStep">
         <p class="Step">Click the
      <span class="hcp1">View queue</span> link at the bottom of the page to enter the Work Queue and apply the adjustments.</p>
      </li>
   </ol>
</div>

説明:

キーを適切に使用してli[@class='kadov-p-CStepBullet']、その最初の先行兄弟の関数としてany を定義しますli[@class='kadov-p-CStep']また、モードの使い分け。


Ⅱ.XSLT 2.0 ソリューション:

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

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

 <xsl:template match="ol[1]">
  <xsl:copy>
   <xsl:apply-templates select="@*"/>
   <xsl:for-each-group select="li"
                       group-starting-with="li[@class='kadov-p-CStep']">
     <xsl:apply-templates select="." mode="inGroup"/>
   </xsl:for-each-group>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="li[@class='kadov-p-CStep']">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>

    <xsl:if test="current-group()[2]">
      <ul>
        <xsl:apply-templates select="current-group()[position() gt 1]" mode="inGroup"/>
      </ul>
    </xsl:if>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="li[@class='kadov-p-CStepBullet']"/>
</xsl:stylesheet>

説明:

xsl:for-each-group属性を持つ命令とgroup-starting-with関数current-group()を使い分ける。また、モードの適切な使用組み込みモード#current#defaultおよびモードのリスト。

于 2012-05-10T02:12:47.823 に答える
0

私の特定のユースケースでは、この部分を.内のfor-eachループの一部にする必要がありました<template match="div">

キーは依然として正解だったので、ソリューションスタイルシートのこの部分をそのまま使用しました。

 <xsl:key name="kFollowing" match="li[@class='kadov-p-CStepBullet']" use="generate-id(preceding-sibling::li[@class='kadov-p-CStep'][1])"/> 

次に、divテンプレートのこの部分は、kadov-p-CStepBullet<li>要素を正しく処理します(このコンテンツをDITAに移行しています)。

 <steps>
   <xsl:for-each select="descendant::li[@class='kadov-p-CStep']">
     <xsl:variable name="vFollowing" select="key('kFollowing', generate-id())"/> 
         <step>
           <cmd>
             <xsl:value-of select="."/>
           </cmd>
           <xsl:if test="following-sibling::li[1][@class='kadov-p-CStepBullet']">
             <info>
               <ul>
               <xsl:for-each select="following-sibling::li[$vFollowing]">
                 <li><xsl:value-of select="."/></li>
               </xsl:for-each>
               </ul>
             </info>
           </xsl:if>
         </step>

ありがとうございました!

于 2012-05-10T16:02:12.453 に答える