Pushing multiple xml through a xsl file to generate a single htmlpage

G

graham.reeds

I am building a reports system. Several events can happen in the space
of an hour so over a long weekend there can be quite a lot of events
(hundreds). Therefore sending everything as a single xml file will
take a long time. Also sending one report at a time would take a long
time for the roundtrip.

What I was going to do was batch up a number of events (say 10) and
then make a request for the next 10. Simple tests show that the first
part of this works (I'm working off the w3schools cd catalog example
with added javascript to hide all but 1 item at a time) but I am
unsure about the second part - specifically the sending of data
through the XSL file and having it append to the original file. As
far as I can see it will overwrite the original html.

Is this possible or am I better off sending individual items through?
 
P

Pavel Lepin

graham.reeds said:
I am building a reports system. Several events can happen
in the space of an hour so over a long weekend there can
be quite a lot of events (hundreds). Therefore sending
everything as a single xml file will
take a long time. Also sending one report at a time would
take a long time for the roundtrip.

What I was going to do was batch up a number of events
(say 10) and then make a request for the next 10. Simple
tests show that the first part of this works (I'm working
off the w3schools cd catalog example...
Eww.

with added javascript to hide all but 1 item at a time)
but I am unsure about the second part - specifically the
sending of data through the XSL file and having it append
to the original file. As far as I can see it will
overwrite the original html.

Is this possible or am I better off sending individual
items through?

Unless I misunderstood your description of the problem, it
seems to me that the thing to do would be to use two
separate transformations.

The first one would aggregate your chunks into the XML
document containing all relevant information (you would
invoke this transformation on current version of aggregate
document, providing, say, filenames of new chunks as
parameters).

The second one would handle the presentation, transforming
your XML document containing aggregated data into the final
HTML document or whatever else.

Oh, and read a *good* tutorial. I believe developerWorks'
library section on XSLT had a decent one.

<http://www.ibm.com/developerworks/xml/>
 
P

Pavel Lepin

Pavel Lepin said:
Unless I misunderstood your description of the problem, it
seems to me that the thing to do would be to use two
separate transformations.

The first one would aggregate your chunks into the XML
document containing all relevant information (you would
invoke this transformation on current version of aggregate
document, providing, say, filenames of new chunks as
parameters).

And here's how it would look in code:

pavel@debian:~/dev/xslt/aggr$ a aggregate.xsl
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:meta="http://example.org/meta-data">
<xsl:param name="chunks"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="data">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:call-template name="process-chunks">
<xsl:with-param name="chunk-list"
select="concat($chunks,',')"/>
</xsl:call-template>
</xsl:copy>
</xsl:template>
<xsl:template name="process-chunks">
<xsl:param name="chunk-list"/>
<xsl:variable name="car"
select="substring-before($chunk-list,',')"/>
<xsl:variable name="cdr"
select="substring-after($chunk-list,',')"/>
<xsl:call-template name="process-chunk">
<xsl:with-param name="chunk" select="$car"/>
</xsl:call-template>
<xsl:if test="$cdr">
<xsl:call-template name="process-chunks">
<xsl:with-param name="chunk-list" select="$cdr"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="process-chunk">
<xsl:param name="chunk"/>
<xsl:if test="not(/data/item[@meta:chunk=$chunk])">
<xsl:apply-templates
select=
"
document(concat('chunk_',$chunk,'.xml'))
/data/item
"
mode="aggregate-chunk-items">
<xsl:with-param name="chunk-name" select="$chunk"/>
</xsl:apply-templates>
</xsl:if>
</xsl:template>
<xsl:template match="data/item"
mode="aggregate-chunk-items">
<xsl:param name="chunk-name"/>
<xsl:copy>
<xsl:attribute name="meta:chunk">
<xsl:value-of select="$chunk-name"/>
</xsl:attribute>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
pavel@debian:~/dev/xslt/aggr$ a data.xml
<data/>
pavel@debian:~/dev/xslt/aggr$ a chunk_1.xml
<data>
<item timestamp="127468743" value="13"/>
<item timestamp="127468746" value="12"/>
<item timestamp="127468749" value="16"/>
<item timestamp="127468750" value="9"/>
<item timestamp="127468755" value="10"/>
</data>
pavel@debian:~/dev/xslt/aggr$ xsltproc --stringparam chunks
1 aggregate.xsl data.xml >data_1.xml
pavel@debian:~/dev/xslt/aggr$ a data_1.xml
<?xml version="1.0"?>
<data><item xmlns:meta="http://example.org/meta-data"
meta:chunk="1" timestamp="127468743" value="13"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="1"
timestamp="127468746" value="12"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="1"
timestamp="127468749" value="16"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="1"
timestamp="127468750" value="9"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="1"
timestamp="127468755" value="10"/></data>
pavel@debian:~/dev/xslt/aggr$ a chunk_2.xml
<data>
<item timestamp="127468762" value="13"/>
<item timestamp="127468763" value="8"/>
<item timestamp="127468769" value="19"/>
</data>
pavel@debian:~/dev/xslt/aggr$ xsltproc --stringparam chunks
2 aggregate.xsl data_1.xml >data_2.xml
pavel@debian:~/dev/xslt/aggr$ a data_2.xml
<?xml version="1.0"?>
<data><item xmlns:meta="http://example.org/meta-data"
meta:chunk="1" timestamp="127468743" value="13"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="1"
timestamp="127468746" value="12"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="1"
timestamp="127468749" value="16"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="1"
timestamp="127468750" value="9"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="1"
timestamp="127468755" value="10"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="2"
timestamp="127468762" value="13"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="2"
timestamp="127468763" value="8"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="2"
timestamp="127468769" value="19"/></data>
pavel@debian:~/dev/xslt/aggr$ a chunk_3.xml
<data>
<item timestamp="127468770" value="21"/>
<item timestamp="127468771" value="7"/>
<item timestamp="127468781" value="18"/>
<item timestamp="127468783" value="9"/>
<item timestamp="127468785" value="2"/>
<item timestamp="127468795" value="11"/>
</data>
pavel@debian:~/dev/xslt/aggr$ xsltproc --stringparam chunks
1,2,3 aggregate.xsl data_2.xml >data_3.xml
pavel@debian:~/dev/xslt/aggr$ a data_3.xml
<?xml version="1.0"?>
<data><item xmlns:meta="http://example.org/meta-data"
meta:chunk="1" timestamp="127468743" value="13"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="1"
timestamp="127468746" value="12"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="1"
timestamp="127468749" value="16"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="1"
timestamp="127468750" value="9"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="1"
timestamp="127468755" value="10"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="2"
timestamp="127468762" value="13"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="2"
timestamp="127468763" value="8"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="2"
timestamp="127468769" value="19"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="3"
timestamp="127468770" value="21"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="3"
timestamp="127468771" value="7"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="3"
timestamp="127468781" value="18"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="3"
timestamp="127468783" value="9"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="3"
timestamp="127468785" value="2"/><item
xmlns:meta="http://example.org/meta-data" meta:chunk="3"
timestamp="127468795" value="11"/></data>
pavel@debian:~/dev/xslt/aggr$
 
G

graham.reeds

That's going to take me some time to digest.

OT: I agree with you on the v5 spec. I dunno why they don't promote
correct xhtml and css better rather than creating a spec that no-one
needs. It seems to be diverging from what I remember of xhtml1.1 (or
was/is now 2.0?).
 
P

Pavel Lepin

graham.reeds said:

That's not altogether OT here, although ciwah might be
somewhat more appropriate for this discussion.
I agree with you on the v5 spec. I dunno why they
don't promote correct xhtml and css better rather than
creating a spec that no-one needs.

Because at least one of the major UA vendors feels XHTML
would represent a somewhat more level playing field, where
it would be harder for them to achieve the lock-in they're
enjoying now. Naturally, that would be detrimental to their
business strategy, and for some reason or other, other W3C
members chose to comply with their wishes in the end.
It seems to be diverging from what I remember of xhtml1.1
(or was/is now 2.0?).

1.1 really was a fluke. It lost all of XHTML 1.0's
crufty 'compatibility' with HTML 4.01, and didn't offer
much in return. Since it was rolled out even before there
was any sort of real support for XHTML 1.0, it never even
had a chance. XHTML2 WG was chartered about a year ago, but
in my opinion Microsoft successfully torpedoed that effort
with the rechartering of HTML WG. Mobile profiles of XHTML
remain our last hope, really, at least we have some sort of
a wedge in the consumer market there, but it still remains
to be seen how much good it is going to do in the long run.
 
A

Andy Dingley

Mobile profiles of XHTML remain our last hope,

Those are dead now too. They might have happened when mobile meant
"mobile phone", but these days a more likely user agent connecting
through a phone network is some sort of mini-Opera on a display of
400px upwards. These clients want the _real_ WWW, not a transcoded
XHTML MP dumbed version of it targeted at sub-200px displays.
 
P

Pavel Lepin

Andy Dingley said:
Those are dead now too. They might have happened when
mobile meant "mobile phone", but these days a more likely
user agent connecting through a phone network is some sort
of mini-Opera on a display of 400px upwards.

My impression was that while XHTML MP support is largely
useless by now, some not-so-enlightened authors still
insist on using it to create new content.

If you're right, oh well, pardon me while I run around in
circles like a headless chicken.
 
J

Joseph Kesselman

graham.reeds said:
unsure about the second part - specifically the sending of data
through the XSL file and having it append to the original file.

XSLT is designed to always generate a new document. If you're trying to
update a document in place, you need to write some code for the purpose.

(XQuery has a proposed extension for mutating a document in place -- see
http://www.w3.org/TR/xquery-update-10/ -- but XQuery is not widely
supported yet and this still-under-development option even less so.)
 
G

graham.reeds

graham.reedswrote:

XSLT is designed to always generate a new document. If you're trying to
update a document in place, you need to write some code for the purpose.

It seems pointless to write what probably amounts to at least a couple
hundred lines of Javascript when XSLT seems to be able to do what I
want it to. And since XSLT seems supported by IE and FF (from my
limited tests) then that seems like the ideal choice.

@Pavel: Can you give a quick run through of your code for me? I think
I have the idea that the code runs from the last section and the
others handle what happens. data_?.xml gets passed in and chunk_?.xml
get's passed out. However the data.xml's don't provide a reference
for the xsl stylesheet. How does the browser know what to do? I'm
going to knock up a quick test with GWT so I can see it in action.
Pity there isn't an XSL debugger than you can step through like java
or c++.

Graham Reeds
 
P

Pavel Lepin

graham.reeds said:
It seems pointless to write what probably amounts to at
least a couple hundred lines of Javascript when XSLT seems
to be able to do what I want it to.

XSLT is a domain-specific language. You stuff an XML
document and a number of parameters into it, you get an XML
document out of it. As Martin said, if you want to
transform in-place, you have to write some code in a
general purpose language of your choice.
@Pavel: Can you give a quick run through of your code for
me?

No. Discussing the actual flow of XSLT processing with
anything but simplest transformations on smallest documents
is not really feasible in Usenet format. You could try
drawing the DOM trees on paper, and running the
transformation by hand. This tends to be a highly
enlightening exercise. Have the reference materials close
by. Don't stop until your results match those produced by
actual XSLT processors.
I think I have the idea that the code runs from the
last section and the others handle what happens.
data_?.xml gets passed in and chunk_?.xml
get's passed out.

Um. Have you read any tutorials but the w3school's one yet?
However the data.xml's don't provide a reference for the
xsl stylesheet.

XSLT PI's are rarely used IME. You can run any
transformation on any document, no matter what the PI says,
and often you want to run more than one transformation on
the document, either sequentially or to get several outputs
in parallel.

XSLT PI's are only useful if their (limited) capabilities
are enough for your purposes, which doesn't seem to be the
case here. Typically, in web context, you invoke your
transformations using the XSLT API in you client- or
server-side scripting language.

Note that in web context you cannot rely on UA being
scriptable, on client-side scripting being enabled and on
XSLT engine being available, with API exposed to the
scripting language. This is only viable in closed
environments. In web context, transform server-side and
serve the results.

Server-side transformations are preferable in any case,
since you have full control over the transformation engine
you're using, and can easily switch engines mid-project
(assuming there is some sort of abstraction layer between
your code and the engine). TransforMiiX and MSXML engines
used by Gecko-baseds and IEs respectively are, generally
speaking, less capable than transformation engines
available elsewhere, such as libxslt, Xalan-J/C++ and,
especially, Saxon, which is on the very few XSLT2-compliant
processors.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,241
Members
46,833
Latest member
BettyeMacf

Latest Threads

Top