xml - How to use XPath and XSLT to process a set of sibling nodes and handle a specific subset of siblings based on two of the siblings -


i have group of sibling elements in xml document need processed xslt table, i'm using apache fop transform pdf. table rows need created whenever 1 of 2 types of elements encountered. cells in row consist of element causes row created in first cell , following siblings in following cells until next element causes row created. here example xml explain better:

    <pre class="prettyprint"><code class="language-xml">         <reqpers>           <person man="four"/>            <person man="a" id="pers_a"/>           <perscat category="recovery supervisor"/>            <person man="b"  id="pers_b"/>           <perscat category="ground personnel"/>            <asrequir/>           <perscat category="as required category"/>           <trade>bill collector</trade>            <person man="c"  id="pers_c"/>           <perscat category="ground personnel"/>           <perskill skill="sk01"/>           <trade>welder</trade>           <esttime>.5 hr</esttime>            <asrequir/>           <perscat category="2nd required category"/>           <esttime>4 days</esttime>            <person man="d"  id="pers_d"/>           <perscat category="rides in chase vehicle"/>           <perskill skill="sk02"/>            <person man="e"/>           <perscat category="jack of trades"/>           <trade>engine mechanic</trade>     </reqpers>    </code>    </pre> 

a row needs created each person or asrequir element, cells row filled group of siblings between these elements. have looked @ lot of examples including: how select siblings

and one:how select group of siblings

as many other's. none of these deal specific problem set, fact there 2 following-siblings deal in xpath query. here example of table should like:

    <pre class="prettyprint"><code class="language-xml">     <table>         <table-header>             <table-row>                 <table-cell> person </table-cell>                 <table-cell> category/trade </table-cell>                 <table-cell> skill level </table-cell>                 <table-cell> trade code </table-cell>                 <table-cell> estimated time </table-cell>             </table-row>         </table-header>         <table-body>             <table-row>                 <table-cell>four</table-cell>                 <table-cell/>                 <table-cell/>                 <table-cell/>                 <table-cell/>             </table-row>             <table-row>                 <table-cell>a</table-cell>                 <table-cell>recovery supervisor</table-cell>                 <table-cell/>                 <table-cell/>                 <table-cell/>             </table-row>             <table-row>                 <table-cell>b</table-cell>                 <table-cell>ground personnel</table-cell>                 <table-cell/>                 <table-cell/>                 <table-cell/>             </table-row>             <table-row>                 <table-cell>as required</table-cell>                 <table-cell/>                 <table-cell/>                 <table-cell>bill collector</table-cell>                 <table-cell/>             </table-row>             <table-row>                 <table-cell>c</table-cell>                 <table-cell>ground personnel</table-cell>                 <table-cell>skill gets converted string value</table-cell>                 <table-cell>welder</table-cell>                 <table-cell>.5 hr</table-cell>             </table-row>             <table-row>                 <table-cell>as required</table-cell>                 <table-cell>2nd required category</table-cell>                 <table-cell/>                 <table-cell/>                 <table-cell>4 days</table-cell>             </table-row>             <table-row>                 <table-cell>d</table-cell>                 <table-cell>rides in chase vehicle</table-cell>                 <table-cell>skill level</table-cell>                 <table-cell/>                 <table-cell/>             </table-row>             <table-row>                 <table-cell>e</table-cell>                 <table-cell>jack of trades</table-cell>                 <table-cell/>                 <table-cell>engine mechanic</table-cell>                 <table-cell/>             </table-row>         </table-body>     </table> </code>        </pre> 

also completeness schema snippet xml i'm processing:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="1.0" <xs:element name="reqpers" type="reqperstype"/> <xs:complextype name="reqperstype">      <xs:sequence>         <xs:element minoccurs="0" ref="applic"/>         <xs:sequence maxoccurs="unbounded">             <xs:choice>                 <xs:element ref="asrequir"/>                 <xs:element ref="person"/>             </xs:choice>             <xs:sequence minoccurs="0">                 <xs:element ref="perscat"/>                 <xs:element minoccurs="0" ref="perskill"/>                 <xs:element minoccurs="0" ref="trade"/>                 <xs:element minoccurs="0" ref="esttime"/>             </xs:sequence>         </xs:sequence>     </xs:sequence>     <xs:attribute ref="refapplic"/>     <xs:attributegroup ref="bodyatt"/>     <xs:attributegroup ref="cntlcontent"/> </xs:complextype> 

here example of xsl code closest i've come, works if there person siblings, once asrequir added things fall apart. repeat code each of cells, replacing perscat element i'm expecting.

    <xsl:for-each select="person | asrequir">             <fo:table-row>                 <fo:table-cell text-align="left" padding-before="1mm" padding-after="1mm" padding-left="1mm" padding-right="1mm">                     <fo:block font-size="10pt">                         <xsl:value-of select="self::person/@man"/>                     </fo:block>                 </fo:table-cell>     <fo:table-cell text-align="left" padding-before="1mm" padding-after="1mm" padding-left="1mm" padding-right="1mm">         <xsl:variable name="perscatsib" select="following-sibling::perscat"/>         <xsl:variable name="perscatprec" select="following-sibling::person[1]/preceding-sibling::perscat"/>         <fo:block font-size="10pt">             <xsl:choose>                 <xsl:when test="$perscatsib[count(. | $perscatprec) = count($perscatprec)]">                     <xsl:value-of select="$perscatsib[count(. | $perscatprec) = count($perscatprec)]/@category"/>                 </xsl:when>                 <xsl:otherwise>                     <xsl:if test="preceding-sibling::person[1] , not(following-sibling::person[1])">                         <xsl:value-of select="following-sibling::perscat[1]/@category"/>                     </xsl:if>                 </xsl:otherwise>             </xsl:choose>         </fo:block>     </fo:table-cell> <continues rest of cells../> 

this table i'm producing:

    <pre class="prettyprint"><code class="language-xml"> <table>     <table-header>         <table-row>             <table-cell> person </table-cell>             <table-cell> category/trade </table-cell>             <table-cell> skill level </table-cell>             <table-cell> trade code </table-cell>             <table-cell> estimated time </table-cell>         </table-row>     </table-header>     <table-body>         <table-row>             <table-cell>four</table-cell>             <table-cell/>             <table-cell/>             <table-cell/>             <table-cell/>         </table-row>         <table-row>             <table-cell>a</table-cell>             <table-cell>recovery supervisor</table-cell>             <table-cell/>             <table-cell/>             <table-cell/>         </table-row>         <table-row>             <table-cell>b</table-cell>             <table-cell>ground personnel</table-cell>             <table-cell/>             **<table-cell>billcollector</table-cell>**             <table-cell/>         </table-row>         <table-row>             <table-cell>as required</table-cell>             <table-cell/>             <table-cell/>             <table-cell>bill collector</table-cell>             <table-cell/>         </table-row>         <table-row>             <table-cell>c</table-cell>             <table-cell>ground personnel</table-cell>             <table-cell>skill gets converted string value</table-cell>             <table-cell>welder</table-cell>             <table-cell>.5 hr</table-cell>         </table-row>         <table-row>             <table-cell>as required</table-cell>             <table-cell>2nd required category</table-cell>             <table-cell/>             <table-cell/>             <table-cell>4 days</table-cell>         </table-row>         <table-row>             <table-cell>d</table-cell>             <table-cell>rides in chase vehicle</table-cell>             <table-cell>skill level</table-cell>             <table-cell/>             <table-cell/>         </table-row>         <table-row>             <table-cell>e</table-cell>             <table-cell>jack of trades</table-cell>             <table-cell/>             <table-cell>engine mechanic</table-cell>             <table-cell/>         </table-row>     </table-body> </table> </code>        </pre> 

the table cell ** around should not have data in it.. adds value following asrequir not want..

i have tried adding following-sibling::person['1']|asrequir['1'] asrequir true siblings in places don't want them. insight or suggestions on how solve problem appreciated. suspect need use grouping of sort or key set, not sure how implement those. while not newbie xslt , xpath, i'm not expert.

a key may group elements reqpers not person or asrequir preceding-sibling person or asrequir.

<xsl:key name="kperson" match="reqpers/*[not(self::person or self::asrequir)]"         use="generate-id(preceding-sibling::*[self::person or self::asrequir][1]) 

the group stats with:

<xsl:for-each select="*[self::person or self::asrequir]"> 

the group members then:

  <xsl:variable name="this" select="." />   <xsl:variable name="group" select=". | key('kperson',generate-id($this))" /> 

get value group:

<xsl:value-of select="$group[self::perscat]/@category"/> 

you may try this:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform">   <xsl:output method="xml" indent="yes"/>    <xsl:key name="kperson" match="reqpers/*[not(self::person or self::asrequir)]"             use="generate-id(preceding-sibling::*[self::person or self::asrequir][1])"/>   <xsl:template match="reqpers">     <table>     <table-header>         <table-row>             <table-cell> person </table-cell>             <table-cell> category/trade </table-cell>             <table-cell> skill level </table-cell>             <table-cell> trade code </table-cell>             <table-cell> estimated time </table-cell>         </table-row>     </table-header>     <xsl:for-each select="*[self::person or self::asrequir]">        <xsl:variable name="this" select="." />       <xsl:variable name="group" select=". | key('kperson',generate-id($this))" />         <table-row>             <table-cell>               <xsl:value-of select="$group[self::person]/@man"/>               <xsl:if test="$group[self::asrequir]" >as required</xsl:if>           </table-cell>             <table-cell><xsl:value-of select="$group[self::perscat]/@category"/></table-cell>             <table-cell><xsl:value-of select="$group[self::perskill]/@skill"/></table-cell>             <table-cell><xsl:value-of select="$group[self::trade]"/></table-cell>             <table-cell><xsl:value-of select="$group[self::esttime]"/></table-cell>          </table-row>     </xsl:for-each>     </table>   </xsl:template>  </xsl:stylesheet> 

with following output:

<table>   <table-header>     <table-row>       <table-cell> person </table-cell>       <table-cell> category/trade </table-cell>       <table-cell> skill level </table-cell>       <table-cell> trade code </table-cell>       <table-cell> estimated time </table-cell>     </table-row>   </table-header>   <table-row>     <table-cell>four</table-cell>     <table-cell/>     <table-cell/>     <table-cell/>     <table-cell/>   </table-row>   <table-row>     <table-cell>a</table-cell>     <table-cell>recovery supervisor</table-cell>     <table-cell/>     <table-cell/>     <table-cell/>   </table-row>   <table-row>     <table-cell>b</table-cell>     <table-cell>ground personnel</table-cell>     <table-cell/>     <table-cell/>     <table-cell/>   </table-row>   <table-row>     <table-cell>as required</table-cell>     <table-cell>as required category</table-cell>     <table-cell/>     <table-cell>bill collector</table-cell>     <table-cell/>   </table-row>   <table-row>     <table-cell>c</table-cell>     <table-cell>ground personnel</table-cell>     <table-cell>sk01</table-cell>     <table-cell>welder</table-cell>     <table-cell>.5 hr</table-cell>   </table-row>   <table-row>     <table-cell>as required</table-cell>     <table-cell>2nd required category</table-cell>     <table-cell/>     <table-cell/>     <table-cell>4 days</table-cell>   </table-row>   <table-row>     <table-cell>d</table-cell>     <table-cell>rides in chase vehicle</table-cell>     <table-cell>sk02</table-cell>     <table-cell/>     <table-cell/>   </table-row>   <table-row>     <table-cell>e</table-cell>     <table-cell>jack of trades</table-cell>     <table-cell/>     <table-cell>engine mechanic</table-cell>     <table-cell/>   </table-row> </table> 

Comments

Popular posts from this blog

html - Styling progress bar with inline style -

java - Oracle Sql developer error: could not install some modules -

How to use autoclose brackets in Jupyter notebook? -