You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by Steve Hathaway <sh...@e-z.net> on 2012/07/30 04:06:49 UTC

XPath Function Internals

Samuel - GSOC 2012

You're doing good.

It looks like you understand the basics of the XPath function class that 
needs to be extended
and customizing the appropriate execute() methods.

Here are some comments:: Ref: file OspXpathConvertDate.cpp from zip example.

YourXPathFunction::execute(
   XPathExecutionContext & executionContext,
   XalanNode *           context,  /*may not be needed*/
   const XObjectPtr      arg1,
   const XObjectPtr      arg2,
   const LocatorType *   locator   /*may not be needed*/
) const
{
   CharVectorType  theFirstArg;
   char *          charFirstArg;
   CharVectorType  theSecondArg;
   char *          charSecondArg;

   MemoryManager * theManager = executionContext.getMemoryManager();

   theFirstArg = TranscodeToLocalCodePage(arg1->str());
   charFirstArg = theFirstArg.begin();

   theSecondArg = TranscodeToLocalCodePage(arg2->str());
   charSecondArg = theSecondArg.begin();

/* NOTES
  *
  * TransCodeToLocalCodePage()
  *   creates a new instance of CharVectorType containing
  *   converted transformed Unicode to the host character set 
(ASCII/EBCDIC...)
  *
  * The CharVectorType.begin() method returns a pointer to the
  * null-terminated character string.  This string is owned by the 
CharVectorType
  * class.  This CharVectorType class is a local variable with local scope.
  * The allocation for CharVectorType will be properly destroyed when the
  * execute() method returns.
  *
  * You should not access the m_data storage variable directly, but instead
  * use the access method begin() to ensure a proper address.
  *
  * Note also that XalanDOMString may not be what you want.  Its native
  * character storage is 16-bit characters (UTF-16) encoding.
  *
  * The above sample I have shown here will give you standard 'C' strings
  * extracted from the XPath function arguments in a safe way.
  *
  * The XalanDOMString class does know how to import data from (char *)
  * strings.
  */

  char * charResult;
  charResult = someFunction(...) // returning a pointer to type (char *);

  // The following creates a XalanDOMString and initializes it with 
charResult.
  // Declaring XalanDOMString as a local instance, it will be destroyed when
  // the execute method exits.

  XalanDOMString theResult(charResult);

  // You may need to free the memory associated with the charResult pointer
  // before you return.  After charResult is saved in a XalanDOMString, you
  // should be able to release owhership of the (char *) pointer and 
free the
  // (char *) allocation.

  free(charResult);  // or program specific equivalent.

  // The execution.GetXObjectFactory() creates a XObjectPtr to data owned
  // by the XObjectFactory.  This content is returned to the XPath
  // interpreter execution context.

  return executionContext.getXObjectFactory().createString(theResult);

}

/*
  * Create an error reporter
  */
const XalanDOMString &
YourXPathFunction::getError(XalanDOMString & theResult) const
{
   return XalanMessageLoader::getMessage(
     theResult,
     XalanMessages::FunctionTakesTwoArguments_1Param,
     "name of you XPath Function");
}

/* NOTE:
  * The example error reporter.
  * The XalanMessageLoader::getMessage(...) prepares a standard message
  * showing theResult, "The function '(0)' requires two arguments."
  * with '(0)' replaced with "name of your XPath Function");
  *
  * If you need messages that are not in the NLS library, we can create
  * new message templates and put them into the NLS library.
  *
  * FunctionTakesTwoArguments_1Param is an address to the NLS string:
  * "The function '(0)' requires two arguments."
  */


Sincerely,
Steven J. Hathaway



---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-dev-help@xml.apache.org


Re: XPath Function Internals

Posted by Gareth Reakes <ga...@we7.com>.
Hey,

	At 1 point it was an path 1 implementation. I can't recall what kind of a test suite it had then but its probably still worth a look. If you have trouble finding the code base for that time period drop me a line and I will see what I can do.

G


On 30 Jul 2012, at 17:28, shathawa@e-z.net wrote:

> Gareth,
> 
> Thanks for the link.  Our first priority is to get additional functionality
> with XPath 1.0 and EXSLT functions.
> 
> I am interested in pursuing the XPath2 integration after our XalanC 1.11
> product is released at the end of summer.  I see this XPath2 integration
> to become XalanC 2.0.
> 
> Sincerely,
> Steven J. Hathaway
> GSoC 2012 mentor
> 
>> Hey Samuel,
>> 
>> 	A long while ago I was one of the people who wrote Pathan (an XPath2
>> implementation on top of Xerces C). Its been replaced with XQilla now
>> (http://xqilla.sourceforge.net/HomePage). I expect its worth a look for
>> function implementations. We also had a thorough test suite which could
>> still be there / be of use.
>> 
>> Cheers,
>> 
>> G
>> 
>> 
>> On 30 Jul 2012, at 03:06, Steve Hathaway wrote:
>> 
>>> Samuel - GSOC 2012
>>> 
>>> You're doing good.
>>> 
>>> It looks like you understand the basics of the XPath function class that
>>> needs to be extended
>>> and customizing the appropriate execute() methods.
>>> 
>>> Here are some comments:: Ref: file OspXpathConvertDate.cpp from zip
>>> example.
>>> 
>>> YourXPathFunction::execute(
>>> XPathExecutionContext & executionContext,
>>> XalanNode *           context,  /*may not be needed*/
>>> const XObjectPtr      arg1,
>>> const XObjectPtr      arg2,
>>> const LocatorType *   locator   /*may not be needed*/
>>> ) const
>>> {
>>> CharVectorType  theFirstArg;
>>> char *          charFirstArg;
>>> CharVectorType  theSecondArg;
>>> char *          charSecondArg;
>>> 
>>> MemoryManager * theManager = executionContext.getMemoryManager();
>>> 
>>> theFirstArg = TranscodeToLocalCodePage(arg1->str());
>>> charFirstArg = theFirstArg.begin();
>>> 
>>> theSecondArg = TranscodeToLocalCodePage(arg2->str());
>>> charSecondArg = theSecondArg.begin();
>>> 
>>> /* NOTES
>>> *
>>> * TransCodeToLocalCodePage()
>>> *   creates a new instance of CharVectorType containing
>>> *   converted transformed Unicode to the host character set
>>> (ASCII/EBCDIC...)
>>> *
>>> * The CharVectorType.begin() method returns a pointer to the
>>> * null-terminated character string.  This string is owned by the
>>> CharVectorType
>>> * class.  This CharVectorType class is a local variable with local
>>> scope.
>>> * The allocation for CharVectorType will be properly destroyed when the
>>> * execute() method returns.
>>> *
>>> * You should not access the m_data storage variable directly, but
>>> instead
>>> * use the access method begin() to ensure a proper address.
>>> *
>>> * Note also that XalanDOMString may not be what you want.  Its native
>>> * character storage is 16-bit characters (UTF-16) encoding.
>>> *
>>> * The above sample I have shown here will give you standard 'C' strings
>>> * extracted from the XPath function arguments in a safe way.
>>> *
>>> * The XalanDOMString class does know how to import data from (char *)
>>> * strings.
>>> */
>>> 
>>> char * charResult;
>>> charResult = someFunction(...) // returning a pointer to type (char *);
>>> 
>>> // The following creates a XalanDOMString and initializes it with
>>> charResult.
>>> // Declaring XalanDOMString as a local instance, it will be destroyed
>>> when
>>> // the execute method exits.
>>> 
>>> XalanDOMString theResult(charResult);
>>> 
>>> // You may need to free the memory associated with the charResult
>>> pointer
>>> // before you return.  After charResult is saved in a XalanDOMString,
>>> you
>>> // should be able to release owhership of the (char *) pointer and free
>>> the
>>> // (char *) allocation.
>>> 
>>> free(charResult);  // or program specific equivalent.
>>> 
>>> // The execution.GetXObjectFactory() creates a XObjectPtr to data owned
>>> // by the XObjectFactory.  This content is returned to the XPath
>>> // interpreter execution context.
>>> 
>>> return executionContext.getXObjectFactory().createString(theResult);
>>> 
>>> }
>>> 
>>> /*
>>> * Create an error reporter
>>> */
>>> const XalanDOMString &
>>> YourXPathFunction::getError(XalanDOMString & theResult) const
>>> {
>>> return XalanMessageLoader::getMessage(
>>>   theResult,
>>>   XalanMessages::FunctionTakesTwoArguments_1Param,
>>>   "name of you XPath Function");
>>> }
>>> 
>>> /* NOTE:
>>> * The example error reporter.
>>> * The XalanMessageLoader::getMessage(...) prepares a standard message
>>> * showing theResult, "The function '(0)' requires two arguments."
>>> * with '(0)' replaced with "name of your XPath Function");
>>> *
>>> * If you need messages that are not in the NLS library, we can create
>>> * new message templates and put them into the NLS library.
>>> *
>>> * FunctionTakesTwoArguments_1Param is an address to the NLS string:
>>> * "The function '(0)' requires two arguments."
>>> */
>>> 
>>> 
>>> Sincerely,
>>> Steven J. Hathaway
>>> 
>>> 
>>> 
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: xalan-dev-unsubscribe@xml.apache.org
>>> For additional commands, e-mail: xalan-dev-help@xml.apache.org
>>> 
>>> 
>> 
>> --
>> Gareth Reakes, CTO         WE7 - Great Music, Free
>> +44-20-7117-0809                    http://www.we7.com
>> 
>> “The music business is a cruel and shallow money trench, a long plastic
>> hallway where thieves and pimps run free, and good men die like dogs.
>> There's also a negative side. “
>> - Hunter S. Thompson
>> 
>> 
>> 
>> 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: xalan-dev-unsubscribe@xml.apache.org
> For additional commands, e-mail: xalan-dev-help@xml.apache.org
> 
> 

-- 
Gareth Reakes, CTO         WE7 - Great Music, Free
+44-20-7117-0809                    http://www.we7.com

“The music business is a cruel and shallow money trench, a long plastic hallway where thieves and pimps run free, and good men die like dogs. There's also a negative side. “
- Hunter S. Thompson




Re: XPath Function Internals

Posted by sh...@e-z.net.
Gareth,

Thanks for the link.  Our first priority is to get additional functionality
with XPath 1.0 and EXSLT functions.

I am interested in pursuing the XPath2 integration after our XalanC 1.11
product is released at the end of summer.  I see this XPath2 integration
to become XalanC 2.0.

Sincerely,
Steven J. Hathaway
GSoC 2012 mentor

> Hey Samuel,
>
> 	A long while ago I was one of the people who wrote Pathan (an XPath2
> implementation on top of Xerces C). Its been replaced with XQilla now
> (http://xqilla.sourceforge.net/HomePage). I expect its worth a look for
> function implementations. We also had a thorough test suite which could
> still be there / be of use.
>
> Cheers,
>
> G
>
>
> On 30 Jul 2012, at 03:06, Steve Hathaway wrote:
>
>> Samuel - GSOC 2012
>>
>> You're doing good.
>>
>> It looks like you understand the basics of the XPath function class that
>> needs to be extended
>> and customizing the appropriate execute() methods.
>>
>> Here are some comments:: Ref: file OspXpathConvertDate.cpp from zip
>> example.
>>
>> YourXPathFunction::execute(
>>  XPathExecutionContext & executionContext,
>>  XalanNode *           context,  /*may not be needed*/
>>  const XObjectPtr      arg1,
>>  const XObjectPtr      arg2,
>>  const LocatorType *   locator   /*may not be needed*/
>> ) const
>> {
>>  CharVectorType  theFirstArg;
>>  char *          charFirstArg;
>>  CharVectorType  theSecondArg;
>>  char *          charSecondArg;
>>
>>  MemoryManager * theManager = executionContext.getMemoryManager();
>>
>>  theFirstArg = TranscodeToLocalCodePage(arg1->str());
>>  charFirstArg = theFirstArg.begin();
>>
>>  theSecondArg = TranscodeToLocalCodePage(arg2->str());
>>  charSecondArg = theSecondArg.begin();
>>
>> /* NOTES
>> *
>> * TransCodeToLocalCodePage()
>> *   creates a new instance of CharVectorType containing
>> *   converted transformed Unicode to the host character set
>> (ASCII/EBCDIC...)
>> *
>> * The CharVectorType.begin() method returns a pointer to the
>> * null-terminated character string.  This string is owned by the
>> CharVectorType
>> * class.  This CharVectorType class is a local variable with local
>> scope.
>> * The allocation for CharVectorType will be properly destroyed when the
>> * execute() method returns.
>> *
>> * You should not access the m_data storage variable directly, but
>> instead
>> * use the access method begin() to ensure a proper address.
>> *
>> * Note also that XalanDOMString may not be what you want.  Its native
>> * character storage is 16-bit characters (UTF-16) encoding.
>> *
>> * The above sample I have shown here will give you standard 'C' strings
>> * extracted from the XPath function arguments in a safe way.
>> *
>> * The XalanDOMString class does know how to import data from (char *)
>> * strings.
>> */
>>
>> char * charResult;
>> charResult = someFunction(...) // returning a pointer to type (char *);
>>
>> // The following creates a XalanDOMString and initializes it with
>> charResult.
>> // Declaring XalanDOMString as a local instance, it will be destroyed
>> when
>> // the execute method exits.
>>
>> XalanDOMString theResult(charResult);
>>
>> // You may need to free the memory associated with the charResult
>> pointer
>> // before you return.  After charResult is saved in a XalanDOMString,
>> you
>> // should be able to release owhership of the (char *) pointer and free
>> the
>> // (char *) allocation.
>>
>> free(charResult);  // or program specific equivalent.
>>
>> // The execution.GetXObjectFactory() creates a XObjectPtr to data owned
>> // by the XObjectFactory.  This content is returned to the XPath
>> // interpreter execution context.
>>
>> return executionContext.getXObjectFactory().createString(theResult);
>>
>> }
>>
>> /*
>> * Create an error reporter
>> */
>> const XalanDOMString &
>> YourXPathFunction::getError(XalanDOMString & theResult) const
>> {
>>  return XalanMessageLoader::getMessage(
>>    theResult,
>>    XalanMessages::FunctionTakesTwoArguments_1Param,
>>    "name of you XPath Function");
>> }
>>
>> /* NOTE:
>> * The example error reporter.
>> * The XalanMessageLoader::getMessage(...) prepares a standard message
>> * showing theResult, "The function '(0)' requires two arguments."
>> * with '(0)' replaced with "name of your XPath Function");
>> *
>> * If you need messages that are not in the NLS library, we can create
>> * new message templates and put them into the NLS library.
>> *
>> * FunctionTakesTwoArguments_1Param is an address to the NLS string:
>> * "The function '(0)' requires two arguments."
>> */
>>
>>
>> Sincerely,
>> Steven J. Hathaway
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: xalan-dev-unsubscribe@xml.apache.org
>> For additional commands, e-mail: xalan-dev-help@xml.apache.org
>>
>>
>
> --
> Gareth Reakes, CTO         WE7 - Great Music, Free
> +44-20-7117-0809                    http://www.we7.com
>
> “The music business is a cruel and shallow money trench, a long plastic
> hallway where thieves and pimps run free, and good men die like dogs.
> There's also a negative side. “
> - Hunter S. Thompson
>
>
>
>



---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-dev-help@xml.apache.org


Re: XPath Function Internals

Posted by Samuel Medeiros <cc...@gmail.com>.
Steven,

thank you for the information.
Now I am able to integrate the developed funtions into the Xalan
architecture.
Your comments are really useful.

Gareth,

I am interested to look at the XQilla project and review the test suite
placed there.
In the Xalan Dates and Times module I have write a suite of unit tests. I
also want to write integration tests to validate this module.
Thank you for the information.

Sincerely,
Samuel Queiroz


2012/7/30 Gareth Reakes <ga...@we7.com>

> Hey Samuel,
>
> A long while ago I was one of the people who wrote Pathan (an XPath2
> implementation on top of Xerces C). Its been replaced with XQilla now (
> http://xqilla.sourceforge.net/HomePage). I expect its worth a look for
> function implementations. We also had a thorough test suite which could
> still be there / be of use.
>
> Cheers,
>
> G
>
>
> On 30 Jul 2012, at 03:06, Steve Hathaway wrote:
>
> Samuel - GSOC 2012
>
> You're doing good.
>
> It looks like you understand the basics of the XPath function class that
> needs to be extended
> and customizing the appropriate execute() methods.
>
> Here are some comments:: Ref: file OspXpathConvertDate.cpp from zip
> example.
>
> YourXPathFunction::execute(
>  XPathExecutionContext & executionContext,
>  XalanNode *           context,  /*may not be needed*/
>  const XObjectPtr      arg1,
>  const XObjectPtr      arg2,
>  const LocatorType *   locator   /*may not be needed*/
> ) const
> {
>  CharVectorType  theFirstArg;
>  char *          charFirstArg;
>  CharVectorType  theSecondArg;
>  char *          charSecondArg;
>
>  MemoryManager * theManager = executionContext.getMemoryManager();
>
>  theFirstArg = TranscodeToLocalCodePage(arg1->str());
>  charFirstArg = theFirstArg.begin();
>
>  theSecondArg = TranscodeToLocalCodePage(arg2->str());
>  charSecondArg = theSecondArg.begin();
>
> /* NOTES
> *
> * TransCodeToLocalCodePage()
> *   creates a new instance of CharVectorType containing
> *   converted transformed Unicode to the host character set
> (ASCII/EBCDIC...)
> *
> * The CharVectorType.begin() method returns a pointer to the
> * null-terminated character string.  This string is owned by the
> CharVectorType
> * class.  This CharVectorType class is a local variable with local scope.
> * The allocation for CharVectorType will be properly destroyed when the
> * execute() method returns.
> *
> * You should not access the m_data storage variable directly, but instead
> * use the access method begin() to ensure a proper address.
> *
> * Note also that XalanDOMString may not be what you want.  Its native
> * character storage is 16-bit characters (UTF-16) encoding.
> *
> * The above sample I have shown here will give you standard 'C' strings
> * extracted from the XPath function arguments in a safe way.
> *
> * The XalanDOMString class does know how to import data from (char *)
> * strings.
> */
>
> char * charResult;
> charResult = someFunction(...) // returning a pointer to type (char *);
>
> // The following creates a XalanDOMString and initializes it with
> charResult.
> // Declaring XalanDOMString as a local instance, it will be destroyed when
> // the execute method exits.
>
> XalanDOMString theResult(charResult);
>
> // You may need to free the memory associated with the charResult pointer
> // before you return.  After charResult is saved in a XalanDOMString, you
> // should be able to release owhership of the (char *) pointer and free the
> // (char *) allocation.
>
> free(charResult);  // or program specific equivalent.
>
> // The execution.GetXObjectFactory() creates a XObjectPtr to data owned
> // by the XObjectFactory.  This content is returned to the XPath
> // interpreter execution context.
>
> return executionContext.getXObjectFactory().createString(theResult);
>
> }
>
> /*
> * Create an error reporter
> */
> const XalanDOMString &
> YourXPathFunction::getError(XalanDOMString & theResult) const
> {
>  return XalanMessageLoader::getMessage(
>    theResult,
>    XalanMessages::FunctionTakesTwoArguments_1Param,
>    "name of you XPath Function");
> }
>
> /* NOTE:
> * The example error reporter.
> * The XalanMessageLoader::getMessage(...) prepares a standard message
> * showing theResult, "The function '(0)' requires two arguments."
> * with '(0)' replaced with "name of your XPath Function");
> *
> * If you need messages that are not in the NLS library, we can create
> * new message templates and put them into the NLS library.
> *
> * FunctionTakesTwoArguments_1Param is an address to the NLS string:
> * "The function '(0)' requires two arguments."
> */
>
>
> Sincerely,
> Steven J. Hathaway
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: xalan-dev-unsubscribe@xml.apache.org
> For additional commands, e-mail: xalan-dev-help@xml.apache.org
>
>
>
> --
> Gareth Reakes, CTO         WE7 - Great Music, Free
> +44-20-7117-0809                    http://www.we7.com
>
> “The music business is a cruel and shallow money trench, a long plastic
> hallway where thieves and pimps run free, and good men die like dogs.
> There's also a negative side. “
> - Hunter S. Thompson
>
>
>
>

Re: XPath Function Internals

Posted by Gareth Reakes <ga...@we7.com>.
Hey Samuel,

	A long while ago I was one of the people who wrote Pathan (an XPath2 implementation on top of Xerces C). Its been replaced with XQilla now (http://xqilla.sourceforge.net/HomePage). I expect its worth a look for function implementations. We also had a thorough test suite which could still be there / be of use.

Cheers,

G


On 30 Jul 2012, at 03:06, Steve Hathaway wrote:

> Samuel - GSOC 2012
> 
> You're doing good.
> 
> It looks like you understand the basics of the XPath function class that needs to be extended
> and customizing the appropriate execute() methods.
> 
> Here are some comments:: Ref: file OspXpathConvertDate.cpp from zip example.
> 
> YourXPathFunction::execute(
>  XPathExecutionContext & executionContext,
>  XalanNode *           context,  /*may not be needed*/
>  const XObjectPtr      arg1,
>  const XObjectPtr      arg2,
>  const LocatorType *   locator   /*may not be needed*/
> ) const
> {
>  CharVectorType  theFirstArg;
>  char *          charFirstArg;
>  CharVectorType  theSecondArg;
>  char *          charSecondArg;
> 
>  MemoryManager * theManager = executionContext.getMemoryManager();
> 
>  theFirstArg = TranscodeToLocalCodePage(arg1->str());
>  charFirstArg = theFirstArg.begin();
> 
>  theSecondArg = TranscodeToLocalCodePage(arg2->str());
>  charSecondArg = theSecondArg.begin();
> 
> /* NOTES
> *
> * TransCodeToLocalCodePage()
> *   creates a new instance of CharVectorType containing
> *   converted transformed Unicode to the host character set (ASCII/EBCDIC...)
> *
> * The CharVectorType.begin() method returns a pointer to the
> * null-terminated character string.  This string is owned by the CharVectorType
> * class.  This CharVectorType class is a local variable with local scope.
> * The allocation for CharVectorType will be properly destroyed when the
> * execute() method returns.
> *
> * You should not access the m_data storage variable directly, but instead
> * use the access method begin() to ensure a proper address.
> *
> * Note also that XalanDOMString may not be what you want.  Its native
> * character storage is 16-bit characters (UTF-16) encoding.
> *
> * The above sample I have shown here will give you standard 'C' strings
> * extracted from the XPath function arguments in a safe way.
> *
> * The XalanDOMString class does know how to import data from (char *)
> * strings.
> */
> 
> char * charResult;
> charResult = someFunction(...) // returning a pointer to type (char *);
> 
> // The following creates a XalanDOMString and initializes it with charResult.
> // Declaring XalanDOMString as a local instance, it will be destroyed when
> // the execute method exits.
> 
> XalanDOMString theResult(charResult);
> 
> // You may need to free the memory associated with the charResult pointer
> // before you return.  After charResult is saved in a XalanDOMString, you
> // should be able to release owhership of the (char *) pointer and free the
> // (char *) allocation.
> 
> free(charResult);  // or program specific equivalent.
> 
> // The execution.GetXObjectFactory() creates a XObjectPtr to data owned
> // by the XObjectFactory.  This content is returned to the XPath
> // interpreter execution context.
> 
> return executionContext.getXObjectFactory().createString(theResult);
> 
> }
> 
> /*
> * Create an error reporter
> */
> const XalanDOMString &
> YourXPathFunction::getError(XalanDOMString & theResult) const
> {
>  return XalanMessageLoader::getMessage(
>    theResult,
>    XalanMessages::FunctionTakesTwoArguments_1Param,
>    "name of you XPath Function");
> }
> 
> /* NOTE:
> * The example error reporter.
> * The XalanMessageLoader::getMessage(...) prepares a standard message
> * showing theResult, "The function '(0)' requires two arguments."
> * with '(0)' replaced with "name of your XPath Function");
> *
> * If you need messages that are not in the NLS library, we can create
> * new message templates and put them into the NLS library.
> *
> * FunctionTakesTwoArguments_1Param is an address to the NLS string:
> * "The function '(0)' requires two arguments."
> */
> 
> 
> Sincerely,
> Steven J. Hathaway
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: xalan-dev-unsubscribe@xml.apache.org
> For additional commands, e-mail: xalan-dev-help@xml.apache.org
> 
> 

-- 
Gareth Reakes, CTO         WE7 - Great Music, Free
+44-20-7117-0809                    http://www.we7.com

“The music business is a cruel and shallow money trench, a long plastic hallway where thieves and pimps run free, and good men die like dogs. There's also a negative side. “
- Hunter S. Thompson