I am working with some pretty messy HTML source content and trying to structure a single ol into one where attributes (from the source) determine if certain list items should be put into their own sub-list. The list is also broken up into several ol, but I think that can be gotten around by ignoring the parent node.
Source:
<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>
</li>
<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>
</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>
</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>
I know, it’s a mess.
So, essentially:
Any li with @class=’kadov-p-CStep’ should be a first-level li.
Any following-sibling li with @class=’kadov-p-CStepBullet’ before the next ‘kadov-p-Step’ li should go in a subordinate list underneath its new parent.
Elsewhere on here, I found a formula for selecting a node-set intersection:
$ns1[count(.|$ns2)=count($ns2)]
Which I have tried to follow in my own (probably very confused) way:
<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')])] ">
This currently produces no results in the output XML. I’m also sure it’s needlessly overengineered.
Thanks for looking, and in advance for any advice you can offer!
I. This XSLT 1.0 transformation:
when applied on the provided XML document:
produces the wanted, correct result:
Explanation:
Appropriate use of a key to define any
li[@class='kadov-p-CStepBullet']as a function of its first preceding-siblingli[@class='kadov-p-CStep']. Also, proper use of modes.II. XSLT 2.0 solution:
Explanation:
Proper use of the
xsl:for-each-groupinstruction with the attributegroup-starting-withand thecurrent-group()function. Also, appropriate use of modes, the built-ing modes#currentand#defaultand a list of modes.