开发者

XSL find a string and start from that point

Sorry about this, but my knowledge of xsl is not fantastic.

I've got some code for constructing a 3 column table from a varying number of node:

<xsl:variable name="t-size" select="count(NewDataSet/VehicleDetail/Options/Option)"/>
   <xsl:variable name="myCount" select="ceiling($t-size div 3)"/>
   <table callpadding="4" cellspacing="0" border="0" id="specificationTbl">
   <xsl:for-each select="NewDataSet/VehicleDetail/Options/Option[position() &lt;= $myCount]">
      <xsl:variable name="here" sel开发者_开发百科ect="position()"/>
         <tr>
           <td class="stiDetail"><xsl:value-of select="."/></td>
           <td class="stiDetail"><xsl:choose>
               <xsl:when test="../Option[$here+$myCount]">
                  <xsl:value-of select="../Option[$here+$myCount]/."/>
               </xsl:when>
               <xsl:otherwise>
               </xsl:otherwise>
               </xsl:choose>
           </td>
           <td class="stiDetail"><xsl:choose>
               <xsl:when test="../Option[$here+$myCount+$myCount]">
                  <xsl:value-of select="../Option[$here+$myCount+$myCount]/."/>
               </xsl:when>
               <xsl:otherwise>
               </xsl:otherwise>
               </xsl:choose></td>
         </tr>
       </xsl:for-each>
   </table></td>

This works fine. But what I'm after is for the loop to scan the nodes for a string value, and then start from the node after the one containing the string.

EG. Here an example XML

<options>
  <option>something</option>
  <option>something</option>
  <option>something</option>
  <option>something</option>
  <option>hello world</option>
  <option>something</option>
  <option>something</option>
  <option>something</option>
  <option>something</option>
  <option>something</option>
  <option>something</option>
</options>

So in the above xml, I would like to scan for the node containing the word "world", then start the table creation from the following node IE. from position 6, onward.

Hope that makes sense.

Any help would be most gratefully received.

Big thanks,

Andy.


<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes" />

    <xsl:template match="/options">
        <table>
            <xsl:apply-templates select="option[contains(., 'world')] | option[contains(., 'world')]/following-sibling::option"/>
        </table>
    </xsl:template>

    <xsl:template match="option">
        <tr>
            <td>
                <xsl:value-of select="."/>
            </td>
        </tr>
    </xsl:template>

</xsl:stylesheet>

Output:

<table>
  <tr>
    <td>hello world</td>
  </tr>
  <tr>
    <td>something</td>
  </tr>
  <tr>
    <td>something</td>
  </tr>
  <tr>
    <td>something</td>
  </tr>
  <tr>
    <td>something</td>
  </tr>
  <tr>
    <td>something</td>
  </tr>
  <tr>
    <td>something</td>
  </tr>
</table>


Use:

/*/*[(.|preceding-sibling::*)[contains(text(),'world')]]

This XPath expression is probably the shortest that selects exactly the wanted set of elements.

XSLT-based verification:

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

 <xsl:template match="/">
     <xsl:copy-of select=
      "/*/*[(.|preceding-sibling::*)[contains(.,'world')]]"/>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the provided XML document:

<options>
    <option>something</option>
    <option>something</option>
    <option>something</option>
    <option>something</option>
    <option>hello world</option>
    <option>something</option>
    <option>something</option>
    <option>something</option>
    <option>something</option>
    <option>something</option>
    <option>something</option>
</options>

the wanted, correct result is produced:

<option>hello world</option>
<option>something</option>
<option>something</option>
<option>something</option>
<option>something</option>
<option>something</option>
<option>something</option>

Alternatively, you could have this transformation:

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

 <xsl:template match="*[(.|preceding-sibling::*)[contains(text(),'world')]]">
     <xsl:copy-of select="."/>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜