A piggy bank of commands, fixes, succinct reviews, some mini articles and technical opinions from a (mostly) Perl developer.

Setting up xemacs xslt-process mode

I set all these options in the environment:

#########################
# copied from /etc/java/java.conf
# JPackage Project
#########################
# Location of jar files on the system
export JAVA_LIBDIR=/usr/share/java
# Location of arch-specific jar files on the system
export JNI_LIBDIR=/usr/lib/java
# List of known java homes (used for autodetection if none is provided)
export JAVA_HOME_LIST=$JAVA_LIBDIR-utils/java_home.list
# Root of all JVM installations
export JVM_ROOT=/usr/lib/jvm
# Default jvm
export JAVA_HOME=$JVM_ROOT/java
# Options to pass to the java interpreter
export JAVACMD_OPTS=
#########################


export CLASSPATH=/usr/share/java

Now when I try to run xslt-process, it says:
Starting the BeanShell. Please wait...

...but then straight away it still always says:
Could not process file, most probably (Xalan1|Saxon) could not be found!

What I think is happening:
  • xalan-2.4.1.jar is installed, not xalan1 as is required.
  • Not all of saxon's dependencies are installed.

Installing an XSLT processor

xsltproc, Saxon or Xalan: http://www.sagehill.net/docbookxsl/InstallingAProcessor.html

Installing Saxon on Linux. Is JAXP 1.3 required? And then how would I test it anyway?

Could install Xalan. But it's already included with Java:
java org.apache.xalan.xslt.EnvironmentCheck

Why can't xemacs' xlst-process mode find any xslt processor?

Simple XSL test

xml.xml file:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="xsl.xsl"?>
<hello-world>
<greeter>An XSLT Programmer</greeter>
<greeting>Hello, World!</greeting>
</hello-world>

xsl.xsl file:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/hello-world">
<HTML>
<HEAD>
<TITLE></TITLE>
</HEAD>
<BODY>
<H1>
<xsl:value-of select="greeting"/>
</H1>
<xsl:apply-templates select="greeter"/>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="greeter">
<DIV>from <I><xsl:value-of select="."/></I></DIV>
</xsl:template>
</xsl:stylesheet>

Working with xemacs XSLT-process mode

M-x xslt-process-mode - enable xslt-process mode
C-c C-x v - run the xslt processor and view results (be sure to type slowly enough!)

M-x customize-group RET xslt-process - options menu: change engine, customise key bindings, etc.

NOTE: the default run command above may have problems under cygwin. Redefine it to C-x C-c C-v and it should work.

xemacs buffer control

C-x b [buffer] [enter] - select or create a named buffer
C-x C-b - list existing buffers
C-x 1 - close the buffer list

Emacs and Cygwin

Can't quit emacs from cygwin?

From within Cygwin, if you start xemacs with: xemacs -nw (for No Window), then C-x C-c to quit emacs does not work. Instead you must type C-g to exit.

xemacs mode line

How to interpret the status line in xemacs:
http://www.xemacs.org/Documentation/21.5/html/xemacs_4.html#SEC10

GNU info

navigate within info screens:














bgo to beginning of the page
?help
mchoose a menu item from the current page (has tab completion)
fchoose a cross-reference to follow (tab completion)
f?list all cross-references on the current page
lgo back to last page

Ctrl-gcancel menu command
isearch index for topic
ddirectory of all info pages
tgo to 'top' of current manual
ssearch forward
qquit info screen

Pass a parameter to XSL in Cocoon

In the sitemap:

<map:transform src="xslt/page.xsl">
<map:parameter name="param1" value="{1}"/>
</map:transform>

In the XSL:

<xsl:param name="param1"/>

...

<xsl:template match="whatever">
<xsl:attribute name="something">
<xsl:value-of select="$param1"/>
</xsl:attribute>
</xsl:template>

XSL variables

Set a variable
<xsl:variable name="something" select="21">

Use a variable
<xsl:value-of select="$something">

You can't change the value of variables.

Emacs

Emacs is desirable for its XSLT debug mode, Emacs::PDE, and font-lock-keywords mode

Viper is a full-featured Vi emulator for GNU Emacs and XEmacs. But if you don't use that, keep reading.

Emacs notes, from the perspective of a vi user

Problems:

* The manual calls for C-h (Ctrl-h) to be used as a special command
** but when using Putty from Windows, by default Ctrl-h just does a backspace.
** from Windows, it can't tell the difference between Ctrl-H and the backspace key
** This means if you re-map Ctrl-H, it also re-maps the Backspace key. I haven't solved this yet.

--------------------------------------------------------

To read the manual on key commands:

1) type F1, i - gets you to the info menu
2) type m, emacs, [enter] - takes you to the Emacs info file
3) Page down to "Fundamental Editing Commands", "Important Text-Changing Commands", etc. and press [enter] on the menu items you want (typing lowercase L takes you

'back' one page)

--------------------------------------------------------

Notes:

* Terminology: C-x means Ctrl-x, C-M-x means Ctrl-Meta-x - the Meta key is Alt under MS Windows)
* For some commands, holding Ctrl is required for the second character (e.g. quit: C-x, C-c), and for others commands it's not (e.g. undo: C-x u)
* Commands like this "M-x set-visited-file-name" mean: type Meta-x, then type the string 'set-visited-file-name'.
* After typing M-x you can also use tab-completion to find commands.

Translation of common Emacs commands for vi users:

commandviemacs

save file:wC-x C-s
save & exit read-only file:wq!C-x, C-c, follow prompts
save to a different file:w fooM-x set-visited-file-name
find a file to open
C-x C-f

delete to end of lineShift-dC-k

undouC-x u

uC-_ (hold Ctrl, press dash/hypen/underscore key)
redorbreak out of undo mode, and type C-_ again

note: these searches are case insensitive
search forward/C-s (incremental / search-as-you-type)

/C-s, [enter] (non incremental / type whole word, then search)
search backward?C-r (incremental)

?C-r, [enter] (non incremental)

note: even these *regex* searches are case insensitive. There is a way to make them case sensitive: set the variable `case-fold-search' to `nil'.
search forward using regex
C-M-s (incremental)
and backward
C-M-r


call out to the shell!M-! (Meta-Shift-1)
start a full subshell
M-x eshell


Notes on differences to vi:

* undo commands wrap around. Once you undo all your edits, the undo command reverses direction and starts re-doing the edits! break out of the undo mode and press C-_ (undo) again to change the direction of undo/redo command.

* files are autosaved to a seperate buffer. to recover after a crash, type: M-x recover-file foo.c


Emacs-only commands:

list commands in help menuF1, ?
get help on key combinationsF1, k, [some key combination]
toggle read-only status of the bufferC-x, C-q
get out of a commandC-g
redo an edit (undo the undo)type any harmless character to break out of undo mode. You will now be able to undo your undo commands.

remove help windowC-x 1
scroll the helpC-M-v

re-map a keyM-x global-set-key [enter]

XSL de-duping

example:

<xsl:choose> <xsl:when test="/session/dataset = 'news'"> <xsl:for-each-group select="item" by="lower-case(title)"> <xsl:apply-templates select="current-group()[1]"> </xsl:apply-templates></xsl:for-each-group> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="item[title != '']"> </xsl:apply-templates></xsl:otherwise>
</xsl:choose>

CSS basics

#id = id
.class = class

PHP 5 XML

SimpleXML
http://www.php.net/manual/en/ref.simplexml.php

$xml = simplexml_load_file($file);

$body = $xml->xpath("//body");

print $body->asXML();


PHP 4 XSL

XSLT extension (for PHP 5, use XSL)
http://www.php.net/manual/en/intro.xslt.php

NOTE:
This extension uses Sablotron and expat, which can both be found at http://www.gingerall.org/sablotron.html. Binaries are provided as well as source.

You must run configure with the --enable-xslt --with-xslt-sablot options.


<?php

$xml 
= <<<EOT
<?xml version="1.0"?>
<hello-world>
    <greeter>An XSLT Programmer</greeter>
    <greeting>Hello, World!</greeting>
</hello-world>
EOT;

$xsl = <<<EOT
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/hello-world">
    <HTML>
      <HEAD>
        <TITLE></TITLE>
      </HEAD>
      <BODY>
        <H1>
          <xsl:value-of select="greeting"/>
        </H1>
        <xsl:apply-templates select="greeter"/>
      </BODY>
    </HTML>
  </xsl:template>
  <xsl:template match="greeter">
    <DIV>from <I><xsl:value-of select="."/></I></DIV>
  </xsl:template>
</xsl:stylesheet>
EOT;

$arguments = array(
     
'/_xml' => $xml,
     
'/_xsl' => $xsl
);

// Allocate a new XSLT processor
$xh xslt_create();

// Process the document
$result xslt_process($xh'arg:/_xml''arg:/_xsl'NULL$arguments);
if (
$result) {
    echo 
"SUCCESS, sample.xml was transformed by sample.xsl into the \$result";
    echo 
" variable, the \$result variable has the following contents\n<br />\n";
    
//echo "<pre>\n";
    
echo $result;
    
//echo "</pre>\n";
} else {
    echo 
"Sorry, sample.xml could not be transformed by sample.xsl into";
    echo 
"  the \$result variable the reason is that " xslt_error($xh);
    echo 
" and the error code is " xslt_errno($xh);
}
xslt_free($xh);

?>

PHP for Mac OSX

PHP arrays

This won't work:
php -r "$a = array( 'c' => array( 'b' => 1 ) );"

But this will:
php -r '$a = Array( "c" => Array( "b" => 1 ) );'

On Mac OSX

PHP command line

php -f file.php

file.php contains:
<?php
print "hello world";
?>

or a one-liner:

php -r "some code;"

Don't forget the trailing semicolon.

PHP 4 XML

DOM XML
http://www.php.net/manual/en/ref.domxml.php
(for PHP 5, use DOM)

Create a Document object from a file:

$doc = xmldocfile("myfile.xml");
if ($doc){
print $doc->dumpmem();
}


NOTE: PHP must be compiled with --with-dom and --with-xml.
phpinfo() will display this information right at the top.

The PHP 4.4.9 (Zend Engine) that comes with Mac OSX is not compiled --with-dom.

PHP 5 XSL


Introduction: The XSL extension implements the XSL standard, performing XSLT transformations using the libxslt library

Requirements: This extension uses libxslt which can be found at http://xmlsoft.org/XSLT/. libxslt version 1.0.18 or greater is required.

Installation: PHP 5 includes the XSL extension by default and can be enabled by adding the argument --with-xsl[=DIR] to your configure line. DIR is the libxslt installation directory.

// xsl document
$xsl = new DomDocument;
$xsl->load($xstemplate);

// xslt processor
$xp = new XsltProcessor();
$xp->importStylesheet($xsl);

// xml document
$xml_doc = new DomDocument;
$xml_doc->load($xmldata);

// perform the transform
$html = $xp->transformToXML($xml_doc);

PHP debug output

ob_start();
print_r( $xml_object );
$output = ob_get_clean();
$this->logger->debug('output=' . $output);

Zend PHP version

Zend Framework 1.5.1 requires PHP 5.1.4 

PHP regular expressions


/(.*)something/s

The s at the end causes the dot to match all characters including newlines.

Use a string to make a variable name

my $rank10 = 42;
{
    no strict 'refs';
    my $num = 10;
    print eval "\$rank$num";
}


result:
    42

Bash profile settings

~/.bash_profile gets called when you log in for the first time. It's your user-specific settings.

~/.bashrc gets called when you start a new shell. Only interactive shells and user scripts read this file.

Type a literal tab in vi

If you've got "convert tabs to spaces" turned on, type this to insert a real tab:
Ctrl-V [tab]

Enjoy logging with Zend

Output to the page within Zend PHP engine:

$writer = new Zend_Log_Writer_Stream('php://output');
$logger = new Zend_Log($writer);
$logger->log('Enjoy this test', Zend_Log::DEBUG);

Or to the webserver error log:

$writer = new Zend_Log_Writer_Stream('php://stderr');
$logger = new Zend_Log($writer);
$logger->debug('Beginning log');