xslt - XSL key to get elements that meet specific criteria -


i working table entry elements , want preceding entry elements in same table pass following test:

parent::row/preceding-sibling::row/entry   [@morerows >= count(parent::row/following-sibling::row     [not(preceding-sibling::row/entry       [generate-id() = $id])])]   [count(preceding-sibling::entry     [not(@morerows)]) + 1 = count(current()/preceding-sibling::entry) + 1] 

the xpath gives me desired result, painfully slow..... use key having problems.

i defined key follows:

<xsl:key name="morerowsentry" match="entry[@morerows]" use="."/> 

while key retrieve entry elements morerows attribute, need retrieve within same ancestor table. well, @ loss how test morerows value. have tried things such :

<xsl:for-each select="key('morerowsentry', (@morerows >= count(parent::row/following-sibling::row[not(preceding-sibling::row/entry[generate-id() = $id])])) , (count(preceding-sibling::entry[not(@morerows)]) + 1 = count(current()/preceding-sibling::entry) + 1))">

i have using xsl 1.0. , appreciated.

some further information:

i converting cals table ooxml. each entry in cals table within row in know there cells missing, need add additional cells. these entry elements have $id generate-id() value of element.

i have xpath above, tests entry elements in preceding rows of table (parent::row/preceding-sibling::row/entry) have morerows attribute greater or equal number of rows between , entry id of $id, , in correct position in empty cell should inserted (count(preceding-sibling::entry[not(@morerows)]) + 1 = count(current()/preceding-sibling::entry) + 1)

simplified sample input:

<table>     <tbody>         <row>             <entry morerows="2">a</entry>             <entry morerows="1">b</entry>             <entry>c</entry>             <entry>d</entry>         </row>         <row>             <entry>e</entry>             <entry>f</entry>         </row>         <row>             <entry>g</entry>             <entry>h</entry>             <entry>i</entry>         </row>         <row>             <entry>j</entry>             <entry>k</entry>             <entry>l</entry>             <entry>m</entry>         </row>     </tbody> </table> 

simplified sample output:

<w:tbl>     <w:tr>         <w:tc>             <w:p>                 <w:r>                     <w:t>a</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>b</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>c</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>d</w:t>                 </w:r>             </w:p>         </w:tc>     </w:tr>     <w:tr>         <w:tc>             <w:tcpr>                 <w:vmerge/>             </w:tcpr>             <w:p/>         </w:tc>         <w:tc>             <w:tcpr>                 <w:vmerge/>             </w:tcpr>             <w:p/>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>e</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>f</w:t>                 </w:r>             </w:p>         </w:tc>     </w:tr>     <w:tr>         <w:tc>             <w:tcpr>                 <w:vmerge/>             </w:tcpr>             <w:p/>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>g</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>h</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>i</w:t>                 </w:r>             </w:p>         </w:tc>     </w:tr>     <w:tr>         <w:tc>             <w:p>                 <w:r>                     <w:t>j</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>k</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>l</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>m</w:t>                 </w:r>             </w:p>         </w:tc>     </w:tr> </w:tbl> 

the input uses morerows attribute specify spanned rows. output requires actual cells inserted <w:vmerge/> element each spanned cell.

another sample:

in sample, there merged columns (specified namest , nameend attributes) must taken in account:

<table>     <tgroup cols="7">         <colspec colname="col1"/>         <colspec colname="col2"/>         <colspec colname="col3"/>         <colspec colname="col4"/>         <colspec colname="col5"/>         <colspec colname="col6"/>         <colspec colname="col7"/>         <tbody>             <row>                 <entry morerows="5">a</entry>                 <entry morerows="1">b</entry>                 <entry morerows="1">c</entry>                 <entry>d</entry>                 <entry>e</entry>                 <entry>f</entry>                 <entry>g</entry>             </row>             <row>                 <entry>2d</entry>                 <entry>2e</entry>                 <entry>2f</entry>                 <entry>2g</entry>             </row>             <row>                 <entry morerows="1">3b</entry>                 <entry morerows="1">3c</entry>                 <entry>3d</entry>                 <entry>3e</entry>                 <entry>3f</entry>                 <entry>3g</entry>             </row>             <row>                 <entry>4d</entry>                 <entry>4e</entry>                 <entry>4f</entry>                 <entry>4g</entry>             </row>             <row>                 <entry morerows="1" nameend="col6" namest="col2">3g - 4g</entry>                 <entry morerows="1">5g</entry>             </row>         </tbody>     </tgroup> </table> 

output:

<w:tbl>     <w:tr>         <w:tc>             <w:tcpr>                 <w:vmerge w:val="restart"/>             </w:tcpr>             <w:p>                 <w:r>                     <w:t>a</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:tcpr>                 <w:vmerge w:val="restart"/>             </w:tcpr>             <w:p>                 <w:r>                     <w:t>b</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:tcpr>                 <w:vmerge w:val="restart"/>             </w:tcpr>             <w:p>                 <w:r>                     <w:t>c</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>d</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>e</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>f</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>g</w:t>                 </w:r>             </w:p>         </w:tc>     </w:tr>     <w:tr>         <w:tc>             <w:tcpr>                 <w:vmerge/>             </w:tcpr>             <w:p/>         </w:tc>         <w:tc>             <w:tcpr>                 <w:vmerge/>             </w:tcpr>             <w:p/>         </w:tc>         <w:tc>             <w:tcpr>                 <w:vmerge/>             </w:tcpr>             <w:p/>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>2d</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>2e</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>2f</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>2g</w:t>                 </w:r>             </w:p>         </w:tc>     </w:tr>     <w:tr>         <w:tc>             <w:tcpr>                 <w:vmerge/>             </w:tcpr>             <w:p/>         </w:tc>         <w:tc>             <w:tcpr>                 <w:vmerge w:val="restart"/>             </w:tcpr>             <w:p>                 <w:r>                     <w:t>3b</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:tcpr>                 <w:vmerge w:val="restart"/>             </w:tcpr>             <w:p>                 <w:r>                     <w:t>3c</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>3d</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>3e</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>3f</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>3g</w:t>                 </w:r>             </w:p>         </w:tc>     </w:tr>     <w:tr>         <w:tc>             <w:tcpr>                 <w:vmerge/>             </w:tcpr>             <w:p/>         </w:tc>         <w:tc>             <w:tcpr>                 <w:vmerge/>             </w:tcpr>             <w:p/>         </w:tc>         <w:tc>             <w:tcpr>                 <w:vmerge/>             </w:tcpr>             <w:p/>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>4d</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>4e</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>4f</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>4g</w:t>                 </w:r>             </w:p>         </w:tc>     </w:tr>     <w:tr>         <w:tc>             <w:tcpr>                 <w:vmerge/>             </w:tcpr>             <w:p/>         </w:tc>         <w:tc>             <w:tcpr>                 <w:gridspan w:val="5"/>             </w:tcpr>             <w:p>                 <w:r>                     <w:t>3g - 4g</w:t>                 </w:r>             </w:p>         </w:tc>         <w:tc>             <w:p>                 <w:r>                     <w:t>5g</w:t>                 </w:r>             </w:p>         </w:tc>     </w:tr> </w:tbl> 

if processor can the exslt:node-set function or equivalent such that provided msxml attack procedurally, using tail-recursive template. ugly, know, , against recommend xslt, in case think way efficiently pass information 1 row next. assuming first row of table have entry every column, how this:

<xsl:template match="tbody">   <w:tbl>     <xsl:apply-templates select="row[1]">       <xsl:with-param name="rowspec">         <!-- build row info structure assuming first row has              right number of entry elements.  nothing spans              first row, @span=0 -->         <xsl:for-each select="row[1]/entry">           <r span="0" />         </xsl:for-each>       </xsl:with-param>     </xsl:apply-templates>   </w:tbl> </xsl:template>  <xsl:template match="row">   <xsl:param name="rowspec" />   <xsl:variable name="therow" select="." />    <w:tr>     <!-- build output row -->     <xsl:for-each select="exsl:node-set($rowspec)/r">       <w:tc>         <xsl:choose>           <xsl:when test="@span = 0">             <!-- row has entry column -->             <xsl:apply-templates select="$therow/entry[                count(current()/preceding-sibling::r[@span = 0]) + 1]" />           </xsl:when>           <xsl:otherwise>             <!-- column spans previous row -->             <w:tcpr>               <w:vmerge/>             </w:tcpr>             <w:p/>           </xsl:otherwise>         </xsl:choose>       </w:tc>     </xsl:for-each>   </w:tr>    <!-- process next row recalculated spans -->   <xsl:apply-templates select="following-sibling::row[1]">     <xsl:with-param name="rowspec">       <xsl:for-each select="exsl:node-set($rowspec)/r">         <xsl:choose>           <xsl:when test="@span = 0">             <!-- had entry element column, use @morerows                  next span, or 0 if doesn't have 1 -->             <xsl:choose>               <xsl:when test="$therow/entry[                  count(current()/preceding-sibling::r[@span = 0]) + 1]/@morerows">                 <r span="{$therow/entry[                  count(current()/preceding-sibling::r[@span = 0]) + 1]/@morerows}" />               </xsl:when>               <xsl:otherwise>                 <r span="0" />               </xsl:otherwise>             </xsl:choose>           </xsl:when>           <xsl:otherwise>             <!-- didn't have entry column, span                  previous row - subtract 1 span when pass on                  next row -->             <r span="{@span - 1}" />           </xsl:otherwise>         </xsl:choose>       </xsl:for-each>     </xsl:with-param>   </xsl:apply-templates> </xsl:template>  <xsl:template match="entry">   <w:p>     <w:r>       <w:t><xsl:value-of select="." /></w:t>     </w:r>   </w:p> </xsl:template> 

(wow, ended more complex expected when started it, i've tested out , seems work correctly). idea here build structure encodes number of rows each column still needs span on @ point row processed. first row we'll have

<r span="0"/> <r span="0"/> <r span="0"/> <r span="0"/> 

then second it'll be

<r span="2"/> <r span="1"/> <r span="0"/> <r span="0"/> 

the third

<r span="1"/> <r span="0"/> <r span="0"/> <r span="0"/> 

etc. each row iterate on this structure rather on entry elements themselves.


edit: you've changed question need account possibility of column spans row spans gets much messier. since we're committed using node-set function, think two-step approach hinted @ larsh, first expand out column spanning entries real entry elements (with attribute identify them such) , process expanded version of xml in place of original.


Comments

Popular posts from this blog

javascript - DIV "hiding" when changing dropdown value -

Does Firefox offer AppleScript support to get URL of windows? -

android - How to install packaged app on Firefox for mobile? -