I’ve been reading the posts out here for awhile around my XSLT problem and can’t seem to find a direct hit anywhere so here goes…
My company has an app that exports notes data from a “core” generated xml format to various file formats needed by our vendors. We handle the transformations of data using XSLT to create LDIF, Specially formatted XML, csv, etc. This application worked flawlessly in r6.5, but has stalled some migration to R7 because we are getting the so familiar error code 4604 when we run transformations in R7.
I’ve stripped the xsl piece by piece and at last have found the line of code that is breaking xalan in notes. To get rid of some very confusing CDATA tag generation one of our XML pros injected a formatting option “cdata-section-elements” which allows us to specify the elements that should be wrapped in cdata tags. (without doing a hack to generate the CDATA tags ourselves) This is the piece which has gone from functional to failing in R7.
Upon querying the parser I still get Xalan-C 1.0 reported back, which is the same info I get from R6.5. Obviously something got refactored by IBM in the R7 release of the Xalan parser or the transformer object.
I am attaching the XSL template for perusal, and am hoping that one of you hardened Lotus Notes XML developers or someone at IBM who is familiar with the XSL transformer and embedded Xalan can notice this post and help… my guess is that the serializer was modified and some change in the name of client side protection ended up making the option I used broken. I’ve stripped almost all overhead out of these files in an effort to reduce anything that would have sent me or anyone down the wrong path.
The xml file is well-formed but not valid, not a problem.
The xsl file is well-formed and valid, but notice I inserted tags so the forum translation won’t trash the CDATA TAGS.
Running in 6.5.4 you will get a successful file generated.
Running in 7.0.2 you will get a couple errors and no file.
=======================THE TEST FILE (LDDTestFileIN.xml)==========================
<?xml version='1.0' encoding='UTF-8'?><header><runtime>20070423_201509</runtime>
<XMLGVersion>XMLG-V0.2c_2004.08.25</XMLGVersion>
<lastrun_dte>04/23/2007 20:11:24</lastrun_dte>
<is_overwrite></is_overwrite>
<notes_generator></notes_generator>
<be_agentServer></be_agentServer>
<controllerPath>f:/public/careerSites/PRODUCTION/SystemControls/data/exportControlSettings.xml</controllerPath>
<fileCreated>2007-04-23T20:15:09-05:00</fileCreated>
</header>
<XMLGL_AJCProfile>
<dataset>
<docID>24B1BDDD5FC2868F85257119006C0C6B</docID>
<DOCUMENTCOUNT>1</DOCUMENTCOUNT>
<AJCProfile>
<officeEmail>myatl@myresources.com</officeEmail>
<officeStreet1>123 Broad Street</officeStreet1>
<officeStreet2>Suite 250</officeStreet2>
<officeCity>Atlanta</officeCity>
<officeState>GA</officeState>
<officeZipCode>30346</officeZipCode>
<officeTollFreePhone>800-123-2587</officeTollFreePhone>
<officeFaxNumber>770-123-8975</officeFaxNumber>
</AJCProfile>
</dataset>
</XMLGL_AJCProfile>
<XMLGL_ComputerJobs>
<dataset>
<DOCUMENTCOUNT>2</DOCUMENTCOUNT>
<JOB>
<FORM>JOB</FORM>
<ADTITLE>ACCOUNT MANAGER - IT Staffing Sales and Recruiting</ADTITLE>
<JOSKILLSOTHERREQUIRED>3+ years of experience in technology sales or IT staffing.;Proven track record of generating new business through prospecting efforts and expanding opportunities through existing relationships. ;Must be self-motivated, be a team player, and possess a high standard of integrity.</JOSKILLSOTHERREQUIRED>
<WEBSKILLSREQUIRED>4 Year Degree;Sales;Account Management;Recruiting</WEBSKILLSREQUIRED>
<WEBSKILLSPREFERRED>IT Staffing</WEBSKILLSPREFERRED>
</JOB>
<JOB>
<FORM>JOB</FORM>
<ADTITLE>ACCOUNT MANAGER - IT Staffing Sales & Recruiting</ADTITLE>
<JOSKILLSOTHERREQUIRED>3+ years of experience in technology sales or IT staffing.;Proven track record of generating new business through prospecting efforts and expanding opportunities through existing relationships. ;Must be self-motivated, be a team player, and possess a high standard of integrity.</JOSKILLSOTHERREQUIRED>
<WEBSKILLSREQUIRED>4 Year Degree;Sales;Account Management;Recruiting</WEBSKILLSREQUIRED>
<WEBSKILLSPREFERRED>IT Staffing</WEBSKILLSPREFERRED>
</JOB>
</dataset>
</XMLGL_ComputerJobs>
======================THE TEMPLATE (LDDTestTemplate.xsl)==========================
<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet xmlns:xsl=“XSLT Namespace” version=“1.0”>
<xsl:output method=“xml” cdata-section-elements=“JOBTITLE JOBPRIMARYSKILLS JOBSECONDARYSKILLS JOBSOFTSKILLS”/>
<xsl:template match="/">
<!-- GLOBAL VARIABLES -->
<xsl:variable name="careerSite">CommunityJobs</xsl:variable>
<xsl:variable name="MyOffice"><xsl:text>My Inc.</xsl:text></xsl:variable>
<xsl:variable name="MyAssociate"><xsl:text>My Associate</xsl:text></xsl:variable>
<xsl:variable name="controllerPath" select="XMLGENDocument/header/controllerPath"/>
<xsl:variable name="parserURL">
<xsl:value-of select="system-property('xsl:vendor-url')"/>
</xsl:variable>
<xsl:variable name="parserVersion">
<xsl:value-of select="system-property('xsl:version')"/>
</xsl:variable>
<!-- END GLOBAL VARIABLES -->
<BODYCONTENT>
<xsl:value-of select=“$parserVersion”/>
<xsl:value-of select=“$parserURL”/>
<xsl:for-each select="XMLGENDocument/XMLGL_ComputerJobs/dataset/JOB">
<COMPONENT>
<JOBTITLE>
<xsl:value-of select="ADTITLE"/>
</JOBTITLE>
<JOBPRIMARYSKILLS>
<xsl:call-template name="replace-delimiter-with-listitem">
<xsl:with-param name="text" select="WEBSKILLSREQUIRED"/>
<xsl:with-param name="from" select="';'"/>
</xsl:call-template>
</JOBPRIMARYSKILLS>
<JOBSECONDARYSKILLS>
<xsl:value-of select="WEBSKILLSPREFERRED"/>
</JOBSECONDARYSKILLS>
<JOBSOFTSKILLS>
<xsl:call-template name="replace-string">
<xsl:with-param name="text" select="JOSKILLSOTHERREQUIRED"/>
<xsl:with-param name="from" select="';'"/>
<xsl:with-param name="to" select="', '"/>
</xsl:call-template>
</JOBSOFTSKILLS>
</COMPONENT>
</xsl:for-each>
</BODYCONTENT>
</xsl:template>
<!--+
| TODO: These should eventually be normalized into a 'global import',
| but due to Notes legacy notes XSL issues, they must be copied into
| every template. 2006.May.11 - plb
+-->
<!-- reusable replace-string function -->
<xsl:template name="replace-string">
<xsl:param name="text"/>
<xsl:param name="from"/>
<xsl:param name="to"/>
<xsl:choose>
<xsl:when test="contains($text, $from)">
<xsl:variable name="before" select="substring-before($text, $from)"/>
<xsl:variable name="after" select="substring-after($text, $from)"/>
<xsl:variable name="prefix" select="concat($before, $to)"/>
<xsl:value-of select="$before"/>
<xsl:value-of select="$to"/>
<xsl:call-template name="replace-string">
<xsl:with-param name="text" select="$after"/>
<xsl:with-param name="from" select="$from"/>
<xsl:with-param name="to" select="$to"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- reusable function to replace the given delimiter with HTML li tags -->
<xsl:template name="replace-delimiter-with-listitem">
<xsl:param name="text"/>
<xsl:param name="from"/>
<xsl:choose>
<xsl:when test="contains($text, $from)">
<xsl:variable name="before" select="substring-before($text, $from)"/>
<xsl:variable name="after" select="substring-after($text, $from)"/><!<InsertLeftBracketHere>CDATA<InsertLeftBracketHere><li>]]><xsl:value-of select="$before"/><!<InsertLeftBracketHere>CDATA<InsertLeftBracketHere></li>]]><xsl:call-template name="replace-delimiter-with-listitem">
<xsl:with-param name="text" select="$after"/>
<xsl:with-param name="from" select="$from"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise><!<InsertLeftBracketHere>CDATA<InsertLeftBracketHere><li>]]><xsl:value-of select="$text"/><!<InsertLeftBracketHere>CDATA<InsertLeftBracketHere></li>]]></xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
===================BUTTON CODE I RAN IN 6.5 AND 7 FOR TESTING==============================
Declarations
Const lsERR_NOTES_XSLT_INPUT_OBJECT = 4519
Const lsERR_NOTES_XSLT_OUTPUT_OBJECT = 4520
Const lsERR_NOTES_XSLT_STYLESHEET_OBJECT = 4521
Sub Click(Source As Button)
%REM
2007.04.23 from the notes help with modification
- Assumes you are taking in xml and transforming to xml
%END REM
On Error Goto genErh
On Error lsERR_NOTES_XSLT_INPUT_OBJECT Goto err_IN
On Error lsERR_NOTES_XSLT_OUTPUT_OBJECT Goto err_OUT
On Error lsERR_NOTES_XSLT_STYLESHEET_OBJECT Goto err_SS
’ * check empties and unsupported
Dim sRoutineName As String
sRoutineName = "XML Transform.click"
Dim errMessage As String
Dim session As New NotesSession
xmlINfilename$ = "LDDtestFileIN"
xslINfilename$ = "LDDtestTemplate"
xmlOUTfilename$ = "LDDtestFileOUT"
pathname$ = "u:\mydata\"
Dim XML_in As NotesStream ' input file
Set XML_in=session.CreateStream
If Not XML_in.Open(pathname$ & xmlINfilename$ & ".xml") Then
Messagebox "Cannot open " & xmlINfilename$,, "XML file error"
Exit Sub
End If
If XML_in.Bytes = 0 Then
Messagebox xmlINfilename$ & " does not exist or is empty",, "XML file error"
Exit Sub
End If
Dim XSL_ss As NotesStream ' style sheet
Set XSL_ss=session.CreateStream
If Not XSL_ss.Open(pathname$ & xslINfilename$ & ".xsl") Then
Messagebox "Cannot open " & xslINfilename$,, "XSL file error"
Exit Sub
End If
Dim XML_out As NotesStream ' output file
Set XML_out=session.CreateStream
If Not XML_out.Open(pathname$ & xmlOUTfilename$ & ".xml") Then
Messagebox "Cannot create " & xmlOUTfilename$,, "File error"
Exit Sub
End If
XML_out.Truncate
Dim transformer As NotesXSLTransformer
Set transformer=session.CreateXSLTransformer(XML_in, XSL_ss, XML_out)
transformer.Process
Exit Sub
err_IN:
Messagebox "XSL Input error", , "XSLTransformer Process"
Exit Sub
err_OUT:
Messagebox "XSL Output error", , "XSLTransformer Process"
Exit Sub
err_SS:
Messagebox "Style Sheet error", , "XSLTransformer Process"
Exit Sub
genErh:
errMessage = "ERROR: line:" + Cstr(Erl) + " msg:" + Error$ + " code:"+ Cstr(Err)
Messagebox errMessage + |
A log may be provided once you dismiss this error prompt.|, , |Transformation Error…|
Messagebox transformer.log + |
******************************
Please use alt+ Print Screen to copy this log to your clipboard
and then paste it into an email or cssr to support.|, , |Transformer Log...|
Exit Sub
End Sub