XML Source
Volume 1: Issue 7: p6.
Directory Lookup With WML and SVG Clients

 #Check if there is 1 cmd line argument
#Print the usage if there are less than no cmd line
 if ( scalar(@ ARGV) < 1)
   print "Usage: createNamelistLDIF. pl <input_ TXT_ file> \r\ n";
   print "Example: createNamelistLDIF. pl employeelist \r\ n";
   print "This will create a ldif file called employeelist. ldif\ r\ n";
   print "Format of entries: Lastname| Firstname| UserId| Employee#| Email| Department| Phone| Location| Building.\ r\ n";
#Array indices start from zero in Perl, so Lastname has index 0, Firstname has index 1 and so on..
   exit 1;
 $SUFFIX = 'joeschmoecompany. com'; #This is the directory suffix for organization attribute (o)
my ($ NAMESLIST) = shift(@ ARGV); # Get the first command line argument, the input file
my ($ LDIF_ FILE) = ">". $NAMESLIST . ". ldif"; #output LDIF file name is <inputfile name>. ldif
my ($ SEPARATOR) = '\| '; #'| ' is the field separator, record separator is a newline charecter
my ($ RECORD, @FIELDS); #declare variables to hold each record, and its fields.
   open( INFILE, $NAMESLIST) or die "Can't open $NAMESLIST file for reading";
   open( OUT, "$ LDIF_ FILE") or die "Can't open $LDIF_ FILE file for writing";

my $ldapRec = 'print OUT qq( dn: uid=$ FIELDS[ 2], ou= people, o=$ SUFFIX); ';
      $ldapRec .= 'print OUT qq(\ ncn: $FIELDS[ 1] $FIELDS[ 0]); ';
      $ldapRec .= 'print OUT qq(\ nemployeenumber: $FIELDS[ 3]); ';
      $ldapRec .= 'print OUT qq(\ nphysicaldeliveryofficename: $FIELDS[ 7]); ';
      $ldapRec .= 'print OUT qq(\ ndepartmentnumber: $FIELDS[ 5]); ';
      $ldapRec .= 'print OUT qq(\ ngivenname: $FIELDS[ 1]); ';
      $ldapRec .= 'print OUT qq(\ nuid: $FIELDS[ 2]); ';
      $ldapRec .= 'print OUT qq(\ nsn: $FIELDS[ 0]); ';
      $ldapRec .= 'print OUT qq(\ ntelephonenumber: $FIELDS[ 6]); ';
      $ldapRec .= 'print OUT qq(\ nmail: $FIELDS[ 4]); ';
      $ldapRec .= 'print OUT qq(\ nl: $FIELDS[ 7]); ';
      $ldapRec .= 'print OUT qq(\ nobjectclass: top); ';
      $ldapRec .= 'print OUT qq(\ nobjectclass: person); ';
      $ldapRec .= 'print OUT qq(\ nobjectclass: organizationalPerson); ';
      $ldapRec .= 'print OUT qq(\ nobjectclass: inetOrgPerson\ n); ';
#Until there are no more records, read each line/ record into $RECORD variable
      while (defined ($ RECORD = <INFILE>))
         chomp $RECORD;
#Remove line endings
         @FIELDS = split($ SEPARATOR, $RECORD); #split the record into fields
#Now, parse and execute the contents of the variable $ldapRec as if it was a perl
# expression. Substitutes current values for all variables.
         eval $ldapRec;
      print "Finished processing \n";

<? xml version=" 1.0"?>
???MP- I would like to see comment lines in a different color!
<!--The PI below instructs Cocoon to process LDAP tags in this XML document -->
 <? cocoon-process type=" ldap"?>
<!--Tell Cocoon to do the Stylesheet transformation after LDAP tags are processed-->
 <? cocoon-process type=" xslt"?>
<!--The media attribute in the PI below indicates the browser type. -->
<!--Cocoon will look at the User-Agent request header and can be -->
<!--configured to handle many of the commonly used browsers. You can -->
<!--change or add your own mappings to the cocoon. properties file. -->
 <!--Please refer to the Cocoon User guide for more information. -->
<? xml-stylesheet href=" lookup-wml. xsl" type=" text/ xsl" media=" wap" ?>
<? xml-stylesheet href=" lookup-svg. xsl" type=" text/ xsl" media=" explorer" ?>
<!--page is the root element for Cocoon XML documents. -->
 <!--Change this to point to your server that hosts your ldap service. -->
      <ldap-server name=" mindstorms. eng">
<!--DO NOT CHANGE LINE BELOW: Cocoon needs the JNDI classes. -->
<!--JNDI stands for Java Naming and Directory Interface. -->
            <initializer> com. sun. jndi. ldap. LdapCtxFactory</ initializer>
 <!--Change the host name and port number as applicable. -->
<!--Port #389 is the default port for the iPlanet Directory Server. -->
             <ldap-serverurl> ldap:// mindstorms. eng: 389</ ldap-serverurl>
         </ ldap-server>
       </ ldap-defs>
<!--Cocoon will throw away all of the LDAP connection info from this -->
<!--document after LDAP processing. -->
<!--Change the server name and the searchbase value -->
    <ldap-query server=" mindstorms. eng" ldap-searchbase=" o= joeschmoecompany. com"> <!--LdapProcessor can substitute values from the servlet request into your query -->
<!--Here it is our GET parameter called "name". We are searching for common name -->
 <!--attributes that have matching value( s) starting with the supplied parameter. -->
cn={@ name}*
   </ ldap-query>
 </ page>

<? xml version=" 1.0"?>
<!--The skeleton for the stylesheet that points to the W3C namespace -->
<xsl: stylesheet version=" 1.0" xmlns: xsl=" http:// www. w3. org/ 1999/ XSL/ Transform">
<!--Match against the occurrence of LDAP search result tag in the XML document -->
 <!--The processing instruction below helps cocoon pick the correct formatter -->
 <!--and generate the right preamble for the output generated. These are parameters -->
<!--from the cocoon. properties file you copied under the Tomcat conf directory. -->
 <xsl: processing-instruction name=" cocoon-format">
type=" text/ wml"
<!--The WML deck is delimited by the "wml" tag below -->
<!--A WML deck is made of cards, which define the UI -->
 <!--and associated logic. A deck must have atleast one -->
<!--This tag delimits the Deck-level events... you can -->
 <!--also define card-level events as you will see shortly.-->
 <!--Here, we're defining a template-based help card. This -->
 <!--looks like the familiar html anchors to another part -->
<!--of the same document, which happens to be a HELP card -->
 <!--we have defined in this deck. -->
      <do type=" options" label=" Help" >
       <go href="# helpcard" />
      </ do>
      </ template>
<!--For each "searchresult" tag we find in the LDAP search results -->
 <!--We select the name, telephone number and email address elements -->
<!--and embed them in paragraph elements -->
      <card id=" startcard" title=" Nametool">
         <xsl: for-each select=" searchresult">
         <xsl: sort select=" givenname" />
            <p> <xsl: value-of select=" sn"/> </ p>
<!--The WML image element "img" has several attributes. The attributes alt and src -->
<!--can have string values that can be displayed in place of an image. The localsrc -->
<!--attribute specifies the name of a ROM or RAM based image, so we are using the -->
 <!--Std WAP names for the icons we want for phone and email information. -->
            <img alt=" Phone:" localsrc=" phone1" src=""/>< xsl: value-of select=" telephonenumber"/> </ p>
            <p> <img alt=" Email:" localsrc=" envelope1" src="" />< xsl: value-of select=" mail"/> </ p>
          </ xsl: for-each>
             <do type=" options" label=" Help" >
             <go href="# helpcard" />
             </ do> </ card>
      <card id=" helpcard">
      <p> Select <em> Go!</ em> to be the first person to use a WAP device for name lookup! </ p>
      </ card>
 </ wml>
</ xsl: template>

(no blank lines allowed) file test.data
SCHMOE| JOE| jschmoe| 3| joe. schmoe@ joeschmoecompany. com| 14777| 6505551212| MenloPark, CA| MenloPark_ Bldg1

 the Perl script on the sample input above. File: test.data.ldif
dn: uid= jschmoe, ou= people, o= joeschmoecompany. com
employeenumber: 3
physicaldeliveryofficename: MenloPark, CA
departmentnumber: 14777
givenname: JOE
uid: jschmoe
telephonenumber: 650 555 1212
mail: joe. schmoe@ joeschmoecompany. com
l: MenloPark, CA
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson

 #add line 195 :
 194:  formatter. type. application/ smil = org. apache. cocoon. formatter. XMLFormatter
 195:  formatter. type. application/ svg-xml = org. apache. cocoon. formatter. XMLFormater
Comment out lines 248 thru 250 (comments begin with '# ' character) and add the lines below:
251 formatter. image/ svg-xml. doctype-public = "-// W3C// DTD SVG 20000802// EN"
252 formatter. image/ svg-xml. doctype-system= "http:// www. w3c. org/ TR/ 2000/ CR-SVG-20000802" 253 formatter. image/ svg-xml. MIME-type= image/ svg-xml

<? xml version=" 1.0"?>
 <xsl: stylesheet version=" 1.0" xmlns: xsl=" http:// www. w3. org/ 1999/ XSL/ Transform" xmlns: xlink=" http:// www. w3. org/ 1999/ xlink/">
<xsl: output method=" xml" indent=" yes" media-type=" image/ svg-xml" />
<!--Variable to specify the vertical offset between the items displayed. -->
<xsl: variable name=" itemOffset" select=" 18" />
<xsl: template match="/">
<!--The processing instruction below helps cocoon pick the correct formatter -->
 <!--and generate the right preamble for the output generated. These are parameters -->
<!--from the cocoon. properties file you copied under the Tomcat conf directory. -->
<xsl: processing-instruction name=" cocoon-format">
      type=" image/ svg-xml"
</ xsl: processing-instruction>
 <!--The SVG file uses css to specify the style on some elements, so this is specified in the output. -->
 <xsl: processing-instruction name=" xml-stylesheet">
      href=" ldap. css" type=" text/ css"
</ xsl: processing-instruction>
<!--Begin SVG page. We need to specify the width and height when declaring the svg root element.--> <!--This version of svg is based on the August 2nd Candidate Recommendation found -->
<!--at: http:// www. w3. org/ TR/ 2000/ CR-SVG-20000802/. -->
 <svg width=" 800">
<!--The height of the SVG image is dependent on the number of matches found. -->
   <xsl: attribute name=" height">
   < xsl: value-of select=" count(/ page/ ldapsearch/ searchresult)* 300" />
   </ xsl: attribute>
 <!--Definition section to be used by SVG elements. -->
<!--Define a filter effect which creates a drop shadow of the SVG element which specifies this effect.--> <!--For this page, this effect is referred to in the css file for the Search Results text (ie the title class). -->
      <filter id=" dropShadow" filterUnits=" ObjectBoundingBox"
          x="-5%" y="-5%" width=" 110%" height=" 110%">
 <!--First blur the mask of the text. -->
         <feGaussianBlur stdDeviation=" 4" in=" SourceAlpha" result=" blur"/>
<!--Offset the blurred text from the original text's position.-->
         <feOffset in=" blur" dy=" 4" dx=" 4" result=" offsetBlur"/>
<!--Flood text with the color black and make it half transparent.-->
         <feFlood style=" flood-color: black; flood-opacity:. 5" result=" halfTransparent"/>
<!--Combine half transparent effect with the blurred offset effect.-->
         <feComposite operator=" in" in=" halfTransparent" in2=" offsetBlur" result=" shadow"/>
<!--Merge the final filter effect with the original text, where, the original text is drawn over the filter--> <!--effect. From this we now have a text with a drop shadow. -->
            <feMergeNode in=" shadow" />
            <feMergeNode in=" SourceGraphic" />
            </ feMerge>
        </ filter>
        </ defs>
<!--Define setElementClass scripting functions which will be used on various SVG elements. -->
      <script><![ CDATA[
                  function setElementClass( evt, className){
                     var element = evt. getTarget();
                     if( element != null)
                        element. setAttribute(" class", className);
         </ script>
<!--Display "Search Results" text. The style for the class "title" is specified in the ldap. css file.-->
         <text x=" 30" y=" 50" class=" title"> Search Results:</ text>
 <!--Apply template for the page element. -->
          <xsl: apply-templates select=" page"/>
    </ svg>
   </ xsl: template>
 <!--Page template -->
 <!--Apply template for the ldapsearch element which has searchresult as a child element.-->
      <xsl: template match=" page">
         <xsl: apply-templates select=" ldapsearch/ searchresult"/>
      </ xsl: template>
<!--Search result template -->
      <xsl: template match=" ldapsearch/ searchresult">
<!--Position each search result entry. By doing a translate, the coordinate -->
 <!--system for this group (ie "g") is reset to this new position -->
             <xsl: attribute name=" transform"> translate( 400, <xsl: value-of select=" 50 + 160  * (position()-1)"/>)
             </ xsl: attribute>
<!--Set up scripting so that for all the child elements of this group object, the style of the -->
<!--text will change depending on whether the mouse -->
<!--is or is not over the text. -->
<!--These classes are specified in the ldap. css file (ie textValueHot and textValue).-->
             <g id=" values" onmouseover=" setElementClass( evt, 'textValueHot')" onmouseout=" setElementClass( evt, 'textValue')">
<!--SVG text elements for the values of this search result entry. UID -->
             <text x=" 5" class=" textValue">< xsl: value-of select="@ ID"/></ text>
<!--Phone and Mailstop -->
            <text y="{$ itemOffset}" x=" 5" class=" textValue">
               < xsl: value-of select=" telephonenumber"/></ text>
            <text y="{ 2*$ itemOffset}" x=" 5" class=" textValue">
                < xsl: value-of select=" physicaldeliveryofficename"/ ></ text>
 <!--Name, location, and employee number -->
            <text y="{ 3*$ itemOffset}" x=" 5" class=" textValue">
               < xsl: value-of select=" givenname"/></ text>
            <text y="{ 4*$ itemOffset}" x=" 5" class=" textValue">
               < xsl: value-of select=" l"/></ text>
            <text y="{ 5*$ itemOffset}" x=" 5" class=" textValue">
               < xsl: value-of select=" employeenumber"/></ text>
<!--Email address (with mailto link) -->
            <a> <xsl: attribute name=" xlink: href">
                       <xsl: text> mailto:</ xsl: text>< xsl: value-of select=" mail"/>
                    </ xsl: attribute>
                   <text y="{ 6*$
itemOffset}" x=" 5" class=" textValue">< xsl: value-of select=" mail"/>
                   </ text>
            </ a>
       </ g>
 <!--SVG text labels for the values of this search result entry. The style for class "textLabel" is --> <!--specified in the ldap. css file. -->
<!--Phone and Mailstop -->
         <text y="{$ itemOffset}" x="-5" class=" textLabel"> Phone</ text>
         <text y="{ 2*$ itemOffset}" x="-5" class=" textLabel"> Mail Stop</ text>
 <!--Name, location, and employee number -->
         <text y="{ 3*$ itemOffset}" x="-5" class=" textLabel"> Name</ text>
         <text y="{ 4*$ itemOffset}" x="-5" class=" textLabel"> Location</ text>
         <text y="{ 5*$ itemOffset}" x="-5" class=" textLabel"> Employee Number</ text>
<!--Email address -->
         <text y="{ 6*$ itemOffset}" x="-5" class=" textLabel"> Email address</ text>
      </ g>
   </ xsl: template>
 </ xsl: stylesheet>

(ldap.css) used in lookup-svg. xsl
.textValue {
   font-family: SunSansCondensed-Demi;
   font-size: 18;
   fill: #666699;
   stroke: none;
   text-anchor: start;
.textValueHot {
   font-family: SunSansCondensed-Demi;
   font-size: 22;
   fill: #aa2222;
   stroke: none;
   text-anchor: start;
.textLabel {
 font-family: SunSansCondensed-Demi;
font-size: 18;
fill: black;
stroke: none;
text-anchor: end;
.title {
font-family: SunSansCondensed-Demi;
font-size: 30;
fill: black;
stroke: none;
start; filter: url(# dropShadow);