Hi, Wendell:
Thanks for your input.
Yes, there are performance concerns, and the way we
current dealt with XSLT jobs is to treat them as async
job and sent it off to be processed in a separate job
server. This strategy has been working well for us
since it alleviates the load on the main transaction
server.
I know it is not a good practice to lock myself
Saxon6.0.2 for this one key feature (I agree with you
that the ability to use variables in xsl:key match/use
is really a bug in XSLT1.0 conformant processor, but a
key feature in XSLT2.0). But on the other hand, this
would not need to be changed once I upgraded to
XSLT2.0. Given how stable Saxon6.0.2 has been and how
little time I have, this could be a reasonable risk to
take at this time. Before that decision is made, it
is certainly good to consider all the options.
To see if there another way to resolve my problem,
below is my original problem, described with source
XML, target XML, my code and explanation in that
order:
Source XML:
<row row="12">
<cell column="1">*Item Name</cell>
<cell column="2">Item Unique ID</cell>
<cell column="3">*Category Unique ID</cell>
<cell column="4">*Item Type</cell>
<cell column="5">*Minimum Desired Quantity</cell>
<cell column="6">Lot Name</cell>
<cell column="7">Description</cell>
</row>
<row row="13">
<cell column="1">item1</cell>
<cell column="2">item1</cell>
<cell column="3">valves</cell>
<cell column="4">single</cell>
<cell column="5">1</cell>
<cell column="6"></cell>
<cell column="7">11</cell>
</row>
<row row="14">
<cell column="1">item2</cell>
<cell column="2">item2</cell>
<cell column="3">valves</cell>
<cell column="4">single</cell>
<cell column="5">2</cell>
<cell column="6">NEWLOT</cell>
<cell column="7">NEWDESC</cell>
</row>
<row row="16">
<cell column="1">*Bid Type</cell>
<cell column="2">*Item Unique ID</cell>
<cell column="3">Supplier Item Code</cell>
<cell column="4">*Price Per Unit</cell>
<cell column="5">Bid Code</cell>
<cell column="6">Currency Code</cell>
<cell column="7">Supplier Organization Code</cell>
</row>
Target XML:
<Requisition RequisitionCode="Default"
RequisitionName="Default">
<LineItem LineItemName="item1" LineItemCode="item1"
LineItemCategoryCode="valves" LineItemType="single"
LineItemMinimumDesiredQuantity="1"
LineItemDescription="11"/>
</Requisition>
<Requisition RequisitionCode="NEWLOT"
RequisitionName="NEWLOT">
<LineItem LineItemName="item2" LineItemCode="item2"
LineItemCategoryCode="valves" LineItemType="single"
LineItemMinimumDesiredQuantity="2"
LineItemDescription="NEWDESC"/>
</Requisition>
My current code in Saxon6.0.2 with xsl:key match/use
contain variables:
<xsl:variable name="LineItemHeader"
select="//row[cell[(_at_)column=1] = '*Item Name'][1]"/>
<xsl:variable name="LineItemHeaderRow"
select="$LineItemHeader/@row"/>
<xsl:variable name="BidHeader"
select="//row[cell[(_at_)column=1] = '*Bid Type'][1]"/>
<!-- assume bid is the last possible section. If bid
header non-existant, set it to the last row + 1 -->
<xsl:variable name="BidHeaderRow">
<xsl:choose>
<xsl:when test="$BidHeader/@row > 0">
<xsl:value-of select="$BidHeader/@row"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//row[last()]/@row + 1"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="LineItemLotColumn"
select="$LineItemHeader/cell[.='Lot Name']/@column"/>
<xsl:key name="lineitemLotsKey" match="//row[(_at_)row
> $LineItemHeaderRow and @row < $BidHeaderRow]"
use="string(cell[(_at_)column=$LineItemLotColumn])"/>
<!-- Lot (Requisitiion) section -->
<xsl:template match="row" mode="Lot">
<xsl:variable name="lotName"
select="string(cell[(_at_)column=$LineItemLotColumn])"/>
<xsl:choose>
<xsl:when test="string($lotName)">
<xsl:element name="Requisition">
<xsl:attribute
name="RequisitionCode"><xsl:value-of
select="$lotName"/></xsl:attribute>
<xsl:attribute
name="RequisitionName"><xsl:value-of
select="$lotName"/></xsl:attribute>
<!-- process each item within the
non-default lot
-->
<xsl:apply-templates
select="key('lineitemLotsKey', $lotName)"
mode="LineItem"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<!-- Default lot is represented with empty
string
or non-existing LineItemLotName attribute -->
<xsl:element name="Requisition">
<xsl:attribute
name="RequisitionCode">Default</xsl:attribute>
<xsl:attribute
name="RequisitionName">Default</xsl:attribute>
<!-- process each item within default
lot -->
<xsl:apply-templates
select="key('lineitemLotsKey', $lotName)"
mode="LineItem"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Explanation:
1. the source XML is generated with a generic Excel to
XML reader. It simply read every row in a Excel
spreadsheet and write to a <row> element. Therefore,
all the row id for each row could change depends on
how many rows are above it.
2. to find the start of each section, variables
LineItemHeaderRow and BidHeaderRow are declared. For
the source XML given above, they would be 12 and 16,
respectively. Note, the bid header row is optional,
therefore it is declared as a conditional variable.
If <row row="16"> element did not exist, BioHeaderRow
would be the last row id + 1, which would be 15 in
this case.
3. a variable LineItemLotColumn is declared to find
the column where "Lot Name" is located. This column
could also change between different files.
4. a key lineitemLotsKey id declared to match all rows
between LineItemHeaderRow and BidHeaderRow and use the
value in LineItemLotColumn cell. Note, both the match
and use contains variables which is non-conform to
XSLT1.0, but somehow allowed by Saxon6.0.2, but not by
Saxon6.2.2/6.4.3/6.5.2. This caused me unable to
upgrade to Saxon6.5.2.
5. a template on row would process the rows based on
the groups created by the key lineitemLotsKey.
6. other limitation worth reiterating is that the XSLT
processor I choose has to work with JDK1.3.1_07, which
is the latest JDK supported by WebLogic6.1.
Hope this provides all the necessary info, let me know
if there are any questions regarding this problem
statement. Any suggestions would be very much
appreciated.
Thanks,
Xiaocun
--- Wendell Piez <wapiez(_at_)mulberrytech(_dot_)com> wrote:
Xiaocun,
At 09:53 AM 6/18/2003, you wrote:
I see. Looks like my options are:
1. investigate forward-walk
2. enhance incoming data (the current design is to
keep process prior to XSLT generic with no business
logic, this will have to break that)
Splitting the process in two could achieve this goal
without having to
break your design principle all the way back. It
should be able to pipeline
your transforms through Saxon using your copy of
WebLogic, or even batch
process them. (Are there performance constraints?)
In fact, I'd propose that if you're trying to
encapsulate your "business
logic" in XSLT, that eventually you'll be wanting to
pipeline in any case.
(Although I should add that a nodeset() function or
its equivalent -- the
application of processing result node sets that
we'll be getting in XSLT 2
-- can be used to emulate a pipeline.)
3. go back to Saxon6.0.2. Somehow variable was
allowed in xsl:key match/use in that version, I had
to
expand the variable out when I upgraded to
Saxon6.5.2,
which is the cause of this problem I am having now.
When the variables are expanded out, the
performance
went down drastically concurrently, which is
another
reason I might decide to go back.
4. wait until WebLogic6.1 supports JDK1.4 and move
up
to Saxon7.5.1 (this probably will never happen)
Since we might want to skip WebLogic7.1, we seems
committed to WebLogic6.1 for an extended period,
therefore option #3 might be the most viable at
this
time for me.
I wouldn't give up on the others. It's a pity to
lock yourself into a
non-conformant version of a tool just for one
"feature". :->
Could we please see your data again, with a concise
restatement of the
problem and perhaps desired output? (Sorry.)
Cheers,
Wendell
___&&__&_&___&_&__&&&__&_&__&__&&____&&_&___&__&_&&_____&__&__&&_____&_&&_
"Thus I make my own use of the telegraph,
without consulting
the directors, like the sparrows, which I
perceive use it
extensively for a perch." -- Thoreau
XSL-List info and archive:
http://www.mulberrytech.com/xsl/xsl-list
__________________________________
Do you Yahoo!?
SBC Yahoo! DSL - Now only $29.95 per month!
http://sbc.yahoo.com
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list