Re: [xsl] lookup table problem

Subject: Re: [xsl] lookup table problem
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Fri, 21 Apr 2006 09:11:26 -0400
At 2006-04-21 14:31 +0200, Alexander.RACHER@xxxxxxxx wrote:
i read many description how to use the document() function with a lookup
table (a second xml file containing information i need to process my xml
source-document), but despite all efforts it didn't work.

following scenario:

in my source-xml i can find following code <positLoco>DE</positLoco>,
whose meaning ( <codeText>) i need to be printed in my resulting fo-file.

this is part of my source file 'dakl.xml' including the code:

  <seife>
     <at.sds.xc.reportService.ReportDaten>
        [...]
     <at.sds.xc.positionsreports.DaklOutput>
       <belegnummerList arraySize="1">
        [...]
       </belegnummerList>
       <depot>
        [...]
       </depot>
       <depotDaten>
        [...]
       </depotDaten>
       <verrechnungskonto>
        [...]
       </verrechnungskonto>
    <einzelPositionList arraySize="5">
     <element>
       <positionsDaten>
         <positSaldoGilt>19998</positSaldoGilt>
         <positVerwahrart>WR</positVerwahrart>
         <positLoco>DE</positLoco>
        [...]

here is a part of the lookup table SVZ_1001.xml

<?xml version="1.0" encoding="ISO-8859-1"?>

<getTables>
 <at.sds.xc.coreService.CodeTableList arraySize="1">
   <element>
     <codeTableNo>1001</codeTableNo>
     <codeTableType>ALLG</codeTableType>
     <codeTableName>code-table-name</codeTableName>
     <codes arraySize="97">
       <element>
         <code>0000</code>
         <hcode/>
         <sysstatus>0</sysstatus>
         <codeText>Wien</codeText>
       </element>
       <element>
        [...]

I need the  <codeText> (lookup) where   <positLoco> (source) equals <code>
(lookup). so, the output should look like
Loco: Wien
(and not '0000').

here is a part of my (wellformed) xsl (template will be called within
fo:root):

<xsl:template name="Posit">
        <xsl:choose>
                <xsl:when test="//einzelPositionList">

Is it true that your instance always has such a list? You don't indicate what your current node is at the time of doing this test. And you are probably inappropriately using "//" here, but I cannot tell for sure.


                        <fo:table table-omit-header-at-break="false"
table-layout="fixed" border-collapse="separate" font-size="8pt" width="
100%">
                        <fo:table-column column-width="35mm"/>
                        <fo:table-column column-width="10mm"/>
                        <fo:table-column column-width="90mm"/>
                        <fo:table-column column-width="30mm"/>
                        <fo:table-column column-width="25mm"/>

                        <fo:table-header>
                                [...]
                        </fo:table-header>
                        <fo:table-body>
                                <xsl:for-each select="
//einzelPositionList/element">
                                        <fo:table-row>
                                        <xsl:attribute name="
background-color">
                                        <xsl:choose>
                                                <xsl:when test="
(position() mod 2) = 0">#ffffff</xsl:when>
                                                <xsl:otherwise>#9ECCFA</
xsl:otherwise>
                                        </xsl:choose>
                                        </xsl:attribute>
                                        <fo:table-cell>
                                                [...]
                                        </fo:table-cell>
                                        <fo:table-cell>
                                                [...]
                                        </fo:table-cell>
                                        <fo:table-cell>
<fo:block>
        <xsl:variable name="loco-svz" select="
document('SVZ_1001.xml')//codes/element = //positDaten/positLoco"/>

Your use of "//" is both wasteful (execution wise) and inappropriate in the above comparison, as the result is not a node set, it is a boolean (which is what you are reading in your error message).


You probably need a predicate something like:

document('SVZ_1001.xml')//codes
              [element = current()/element/positDaten/positLoco]"

But, unfortunately, you don't give enough of your code, and your constant jumping back to the root using "//" is probably losing your context for the purposes of efficient testing and navigation.

        <xsl:if test="normalize-space(./positionsDaten/positLoco) != $leer
">

You don't show the setting of the variable $leer, so I'm not sure how this helps.


fop - message:
Exception
org.apache.xpath.XPathException: #BOOLEAN kann nicht in NodeList
konvertiert werden!
(means: boolean can not be coverted into nodelist)

Right ... because you were initializing your variable to the result of a comparison operator ... not a selection of a qualified node list.


how do i need to write my xsl to get things working as i expect?

Probably quite a few changes are needed.


I tell my students "if you think you need "//" then think again ... you probably don't ... which isn't to say it is evil, just that it has its role and it is too often abused".

I hope this helps.

. . . . . . . . . Ken

--
Registration open for XSLT/XSL-FO training: Wash.,DC 2006-06-12/16
Also for XSLT/XSL-FO training:    Minneapolis, MN 2006-07-31/08-04
Also for XML/XSLT/XSL-FO training:Birmingham,England 2006-05-22/25
Also for XSLT/XSL-FO training:    Copenhagen,Denmark 2006-05-08/11
World-wide on-site corporate, govt. & user group XML/XSL training.
G. Ken Holman                 mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
Box 266, Kars, Ontario CANADA K0A-2E0    +1(613)489-0999 (F:-0995)
Male Cancer Awareness Aug'05  http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal

Current Thread