Friday, 18 May 2012

count preceding siblings in a flat structure

If there was a degree in the bleeding obvious I swear I would fail it.
A recent need to create an xpath to find the number of preceding siblings from a specific point in those preceding siblings was perplexing me. The xml was something like:
<items>
    <item/>
    <item/>
    <item/>
    <item/>
    <item marker="true"/>
    <item/>
    <item/>
    <item/>
    <item/>
    <item/>
    <item/>
    <item/>
    <item/>
    <item/>
    <item/>
    <item/>
</items>
What was needed was an xpath to calculate how many preceding siblings an item element was from the item element with the marker attribute. After playing around a little, I came up with:
count(preceding-sibling::*[preceding-sibling::*/generate-id() = current()/preceding-sibling::*[@marker = 'true'][1]/generate-id()])
which worked a treat but was rather over-wieldy. It wasn't until looking at this from an Arbortext Styler persepective which refused to accept the current() and generate-id() functions (probably because these are xslt only functions rather than true xpath functions) that the bleeding obvious poked its head up and whacked me around the chops with a proverbial wet fish.
count(preceding-sibling::*) - count(preceding-sibling::*[@marker='true'][1]/preceding-sibling::*)
simple when you think about it!

Monday, 30 April 2012

create Admin account on Vista


Enable the Administrator Account

  1. Open the command prompt with Administrative privileges by opening the Start Menu, and typing cmd in the search box, and then press Ctrl+Shift+Enter or click the Start orbAll ProgramsAccessories, right-click Command Promptand select Run as administrator.
  2. Type the following in the command prompt and press Enter after:
    net user administrator /active:yes
  3. Restart your computer and logon as Administrator.

Saturday, 17 December 2011

XSLT Title Case Converter


<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:griffmonster="http://www.griffmonster.com/functions" exclude-result-prefixes="griffmonster">

<!-- title case converter module

takes a string input and converts to title case as output

uses an exceptions file for word exceptions

created  griffmonster -->


 <xsl:param name="strExceptionsFilename">titleCaseExceptions.xml</xsl:param>

 <xsl:param name="nstExceptions" select="document($strExceptionsFilename)"/>

 <xsl:function name="griffmonster:fnTitleCase">
  <xsl:param name="string"/>
  <xsl:variable name="intLength" select="string-length($string)"/>
  <xsl:variable name="tokenizedSample" select="tokenize($string,'\s')"/>
  <xsl:for-each select="$tokenizedSample">
   <xsl:variable name="strToken" select="."/>
   <xsl:choose>
    <xsl:when test="$nstExceptions//Exception[lower-case(self::*) = lower-case($strToken)]">
     <xsl:value-of select="$nstExceptions//Exception[lower-case(self::*) = lower-case($strToken)]"/>
    </xsl:when>
    <!--Filter for name begining with O' -->
    <xsl:when test='starts-with(lower-case($strToken),"o&apos;")'>
     <xsl:value-of select="upper-case(substring($strToken, 1, 3))"/>
     <xsl:value-of select="lower-case(substring($strToken, 4, $intLength))"/>
    </xsl:when>
    <!-- filter for names begining with 'Mc' -->
    <xsl:when test="starts-with(lower-case($strToken),'mc')">
     <xsl:value-of select="upper-case(substring($strToken, 1, 1))"/>
     <xsl:value-of select="lower-case(substring($strToken, 2, 1))"/>
     <xsl:value-of select="upper-case(substring($strToken, 3, 1))"/>
     <xsl:value-of select="lower-case(substring($strToken, 4, $intLength))"/>
    </xsl:when>
    <!--filter for hyphenated names-->
    <xsl:when test="contains(lower-case($strToken),'-')">
     <xsl:variable name="tokenizedHyphen" select="tokenize($strToken,'-')"/>
     <xsl:for-each select="$tokenizedHyphen">
      <xsl:value-of select="upper-case(substring(., 1, 1))"/>
      <xsl:value-of select="lower-case(substring(., 2))"/>
      <xsl:if test="position() != last()">
       <xsl:text>-</xsl:text>
      </xsl:if>
     </xsl:for-each>
    </xsl:when>
    <!--filter for postcodes-->
    <xsl:when test="matches($strToken,'[A-Z][A-Z]?[0-9][0-9]?') or matches($strToken,'[0-9][A-Z]{2}')">
     <xsl:value-of select="."/>
    </xsl:when>
    <xsl:otherwise>
     <xsl:value-of select="upper-case(substring($strToken, 1, 1))"/>
     <xsl:value-of select="lower-case(substring($strToken, 2, $intLength))"/>
    </xsl:otherwise>
   </xsl:choose>
   <xsl:choose>
    <xsl:when test="position() != last() and matches($strToken,'[A-Z][A-Z]?[0-9][0-9]?')">
     <xsl:text>&#160;</xsl:text>
    </xsl:when>
    <xsl:when test="position() != last()">
     <xsl:text> </xsl:text>
    </xsl:when>
   </xsl:choose>
  </xsl:for-each>
 </xsl:function>
</xsl:stylesheet>

<!-- Exceptions file can be  added thus

<Exceptions>
 <Exception description="Example Company Ltd">ECL</Exception>
 <Exception>GriffMonster</Exception>
 <Exception description="acronym for Limited Liability Partnership">LLP</Exception>
 <Exception>UK</Exception>
 <Exception>in</Exception>
 <Exception>aka</Exception>
</Exceptions>

Thursday, 23 August 2007

XSLT Maths operators

Here is a stylesheet to example XSLTs maths operators

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes"/>

<xsl:template match="numbers">
A. 4 + 3.2 = <xsl:value-of select="x + y"/>
B. 3.2 - 4 = <xsl:value-of select="y - x"/>
C. 4 * 3.2 = <xsl:value-of select="x * y"/>
D. 11/3.2 = <xsl:value-of select="z div y"/>
E. 4 + 3.2 * 11 = <xsl:value-of select="x+y*z"/>
F. (4 + 3.2) * 11 = <xsl:value-of select="(x+y)*z"/>
G. 11 mod 4 = <xsl:value-of select="z mod x"/>
H. 4 + 3.2 + 11 = <xsl:value-of select="sum(*)"/>
I. floor(3.2) = <xsl:value-of select="floor(y)"/>
J. ceiling(3.2) = <xsl:value-of select="ceiling(y)"/>
K. round(3.2) = <xsl:value-of select="round(y)"/>
L. 11 + count(*) = <xsl:value-of select="11+count(*)"/>
M. 3.2 + string-length("3.2") =
<xsl:value-of select="y + string-length(y)"/>
N. 11 + "hello" = <xsl:value-of select="z + 'hello'"/>
</xsl:template>

</xsl:stylesheet>

this results in:

A. 4 + 3.2 = 7.2
B. 3.2 - 4 = -0.8
C. 4 * 3.2 = 12.8
D. 11/3.2 = 3.4375
E. 4 + 3.2 * 11 = 39.2
F. (4 + 3.2) * 11 = 79.2
G. 11 mod 4 = 3
H. 4 + 3.2 + 11 = 18.2
I. floor(3.2) = 3
J. ceiling(3.2) = 4
K. round(3.2) = 3
L. 11 + count(*) = 14
M. 3.2 + string-length("3.2") =
6.2
N. 11 + "hello" = NaN

Wednesday, 8 August 2007

convert to camel case using XPath 2

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:str="http://www.metaphoricalweb.org/xmlns/string-utilities"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="2.0">
<xsl:function name="str:title-case" as="xs:string">
<xsl:param name="expr"/>
<xsl:variable name="tokens" select="tokenize($expr,' ')"/>
<xsl:variable name="titledTokens" select="for $token in $tokens return
concat(upper-case(substring($token,1,1)),
lower-case(substring($token,2)))"/>
<xsl:value-of select="string-join($titledTokens,'')"/>
</xsl:function>
<xsl:template match="/">
<data><xsl:value-of select="str:title-case('This is a test')"/></data>
</xsl:template>
</xsl:stylesheet>

Friday, 6 July 2007

Setting up the Saxon Servlet

I found very little documentation on how to do implement the Saxon Servlet and get it working - so here goes.
1. Install Tomcat - I have Tomcat v6 already installed. It was the basic installation.
2. in webapps add a directory called xslt
copy the files to the following locations:
xslt
  |
  WEB-INF
      web.xml
    |
    classes
      SaxonServlet.class
    |
    lib
      Saxon8.jar + other saxon jars

web.xml consists of the following lines:
<web-app>
<display-name>Saxon Servlet Example</display-name>
<description>
Saxon Servlet Example
</description>
<servlet>
<servlet-name>SaxonServlet</servlet-name>
<servlet-class>SaxonServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SaxonServlet</servlet-name>
<url-pattern>/SaxonServlet</url-pattern>
</servlet-mapping>
</web-app>


then use the following url to calls the transformation:
http://localhost:8080/xslt/SaxonServlet?source=books.xml&style=books.xsl

and to clear the stylesheet cache:
http://localhost:8080/xslt/SaxonServlet?clear-stylesheet-cache=yes

Thursday, 5 July 2007

XSLT Generating lists in InDesign Interchange

Lists within the INX format are wrapped in a <pcnt> element. Each list item is generated by a carriage return - there are no child elements to define a list item. This becomes an issue when processing inline elements from the source. The way I have overcome this is to have a two stage process. The template for a list applies templates in a given mode and hold the node-set in a variable, this variable is then transformed in another mode:
<xsl:template match="ul">
<xsl:variable name="list">
<xsl:apply-templates mode="inline"/>
</xsl:variable>
<xsl:apply-templates select="$list" mode="out"/>
</xsl:template>
Without this method the result contains elements for each list item.