This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Generating a list of items NOT present in source XML


> I'm wondering if anyone has created a template (or has ideas on how 
> to efficiently create such) that generates a list of items that is 
> missing from a given source document.  Assume that a node-set is 
> passed that contains an assorted cluster of indices, the template 
> should start at one, and continue to the highest provided element, 
> outputting all missing elements.
> 
>    For example, the source document:
> <root>
>    <obj><childnode>3</childnode></obj>
>    <obj><childnode>5</childnode></obj>
>    <obj><childnode>9</childnode></obj>
>    <obj><childnode>5</childnode></obj>
>    <obj><childnode>4</childnode></obj>
>    <obj><childnode>1</childnode></obj>
>    <obj><childnode>7</childnode></obj>
> </root>
> 
> might produce
> 
> <missing>
>    <obj><childnode>2</childnode></obj>
>    <obj><childnode>6</childnode></obj>
>    <obj><childnode>8</childnode></obj>
> </missing>
> 
> when passed through such a template.
> 
>    I figure one way to do this is to first sort the node-set 
> (possibly using a parameter to identify the indexed node), and then 
> apply a template on all children that don't have an index that is 1 
> less than that of the following sibling.  But there are problems 
> there when there are 2 consecutively missing nodes.  Any ideas?

Hi Greg,

With FXSL it is straightforward to iterate any given number of times.
The function scanIter() can be used in your case.

Bellow is an utility function generateBatch() that you can call to fill
any gap in your xml nodes:

<xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  xmlns:vendor="urn:schemas-microsoft-com:xslt"
  xmlns:myIncrement="f:myIncrement" 
  exclude-result-prefixes="vendor myIncrement" 
 >
 
 <xsl:import href="iter.xsl"/>
 
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 
  <xsl:template match="/">
    <xsl:call-template name="generateBatch">
      <xsl:with-param name="pFrom" select="3"/>
      <xsl:with-param name="pTo" select="7"/>
    </xsl:call-template>
  </xsl:template>
  
  <myIncrement:myIncrement/>
  
  <xsl:template name="generateBatch">
    <xsl:param name="pFrom"/>
    <xsl:param name="pTo"/>
    
    <xsl:variable name="vFunIncr" 
         select="document('')/*/myIncrement:*[1]"/>
    
    <xsl:variable name="vResult">
      <xsl:call-template name="scanIter">
        <xsl:with-param name="arg1" select="$pTo - $pFrom + 1"/>
        <xsl:with-param name="arg2" select="$vFunIncr"/>
        <xsl:with-param name="arg3" select="$pFrom - 1"/>
        <xsl:with-param name="arg4" select="'obj'"/>
      </xsl:call-template>
    </xsl:variable>
    
    <xsl:copy-of select="vendor:node-set($vResult)/*[position() > 1]"/>
   </xsl:template>
   
   <xsl:template match="myIncrement:*">
     <xsl:param name="arg1"/>
       <childnode>
       <xsl:value-of select="$arg1 + 1"/>
       </childnode>
   </xsl:template>

</xsl:stylesheet>

When applied to any source xml, the above transformation will test the
generateBatch() function to generate missing nodes with values from 3
to 7. The result is:

<obj><childnode>3</childnode></obj>
<obj><childnode>4</childnode></obj>
<obj><childnode>5</childnode></obj>
<obj><childnode>6</childnode></obj>
<obj><childnode>7</childnode></obj>

Cheers,
Dimitre Novatchev.



__________________________________________________
Do You Yahoo!?
LAUNCH - Your Yahoo! Music Experience
http://launch.yahoo.com

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]