someone11 Posted September 14, 2008 Share Posted September 14, 2008 What I want to do is split up a big xml file into smaller ones based on the "category" attribute inside the <course> elements of my xml file. I've successfully found a way to do this using Xalan and redirect:write, but when there are multiple "category" attributes with the same name only the last one is written to the output file.I got around this by setting append="true" to the redirect tag, however now I have multiple namespace and process-instruction declarations for each <course> element!? Arggghhh.How can I solve this? Do I have to use <xsl:for-each select="???"> somewhere? I'm confused.Thank you for your time and help in advance, and I'm using JDK 6 and Xalan 2.7.1spring.xml <?xml version="1.0" encoding="UTF-8"?><spring><course category="Business & Management" id="BUSS470"><link>../html/courses/business.html</link><title>Business Negotiations</title><desc>N/A</desc><textbook>N/A</textbook><inst>Barry Floyd</inst><bio>N/A</bio><number>BUS S470</number><start_date><month>06</month>/<day>23</day>/<year>08</year></start_date><end_date><month>08</month>/<day>18</day>/<year>08</year></end_date><reglink></reglink><time>Mon. 5:30 pm - 10:30 pm</time><location>TBA</location><meetings>9</meetings><fee>$</fee><units>4.0 Quarter Units</units><note></note></course><course category="Languages" id="DEV1E867"><link>../html/courses/languages.html</link><title>Conversational Spanish I</title><desc>N/A</desc><textbook>N/A</textbook><inst>N/A</inst><bio>N/A</bio><number>DEV1 E867</number><start_date><month>06</month>/<day>24</day>/<year>08</year></start_date><end_date><month>08</month>/<day>26</day>/<year>08</year></end_date><reglink></reglink><time>Tuesday 6:10 pm - 8:10 pm</time><location>TBA</location><meetings>10</meetings><fee>$</fee><units>2.0 CEUs</units><note></note></course><course category="Languages" id="DEV1E880"><link>../html/courses/languages.html</link><title>Conversational Spanish II</title><desc>N/A</desc><textbook>N/A</textbook><inst>N/A</inst><bio>N/A</bio><number>DEV1 E880</number><start_date><month>10</month>/<day>02</day>/<year>08</year></start_date><end_date><month>12</month>/<day>11</day>/<year>08</year></end_date><reglink></reglink><time>Thurs. 6:10-8:10pm</time><location>TBA</location><meetings>10</meetings><fee>$</fee><units>2.0</units><note></note></course></spring> course_split.xsl <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:redirect="http://xml.apache.org/xalan/redirect" extension-element-prefixes="redirect" version="1.0"><xsl:output method="xml"/><xsl:template match="/"><xsl:apply-templates/></xsl:template><xsl:template match="spring"><xsl:apply-templates/></xsl:template><xsl:template match="course"><xsl:variable name="filename" select="concat(@category,'.xml')"/><redirect:write select="$filename" append="true"><xsl:processing-instruction name="xml-stylesheet">href="courseformatting.xsl" type="text/xsl"</xsl:processing-instruction><course category="{@category}" id="{@id}"><xsl:apply-templates/></course></redirect:write></xsl:template><xsl:template match="link | title | desc | textbook | inst | bio | number | start_date | end_date | reglink | time | location | meetings | fee | units | note"><xsl:copy-of select="."/></xsl:template></xsl:stylesheet> Link to comment Share on other sites More sharing options...
boen_robot Posted September 14, 2008 Share Posted September 14, 2008 It might be wise if you use another environment to adjust the XMLs if feasable. It will be easier, that's for sure.For example, in PHP, once you've created all of your documents with on PIs, you can loop over the documents, DOMDocument::load() them, and append the PI to the top.If you really want to do it in pure XSLT, I think the best way may be to have a second XSLT transformation on top of this one - generate a new XML document that will serve as a map of the ones that were created, then perform a second transformation over that document that will fetch all XMLs with document(), add the PI and copy the rest.Ideally, forget the PI and switch to server side XSLT processing. Link to comment Share on other sites More sharing options...
someone11 Posted September 14, 2008 Author Share Posted September 14, 2008 That's the problem, I cannot use server side processing because dynamic pages are not allowed on the servers.And in regards to two XSLT transformations that's exactly what I'm doing, or at least I think thats what you mean. If you notice the href on the PI it points to courseformatting.xsl, which is what styles the outputted xml from the course_split.xsl (Sorry I'm confused )courseformatting.xsl ... <div id="info"> <xsl:for-each select="course"> <h2><xsl:value-of select="title"/></h2> <p><xsl:value-of select="desc"/></p> <p><xsl:text>Textbook: </xsl:text><xsl:value-of select="textbook"/></p> <p><strong><em><xsl:value-of select="inst"/></em></strong><em> <xsl:value-of select="bio"/></em></p> <p><strong><xsl:value-of select="number"/></strong><br /> <xsl:value-of select="start_date"/><xsl:text>–</xsl:text><xsl:value-of select="end_date"/><br /> <a href="{reglink}">Register online for <em><xsl:value-of select="title"/></em></a><br /> <xsl:value-of select="time"/><br /> <xsl:text>Location: </xsl:text><xsl:value-of select="location"/><br /> <xsl:value-of select="meetings"/><xsl:text> meeting(s)</xsl:text><br /> <xsl:text>Fee: </xsl:text><xsl:value-of select="fee"/><br /> <xsl:value-of select="units"/><br /> <xsl:value-of select="note"/></p> <p align="right"><a href="#wrapper">Return to Top</a></p> <hr size="1" /> </xsl:for-each> </xsl:template></xsl:stylesheet> Link to comment Share on other sites More sharing options...
boen_robot Posted September 14, 2008 Share Posted September 14, 2008 I mean two Xalan invocations (+ the last one with the PI). I guess that makes a total of 3 XSLT transformations.I know it's too much, but when you lack server side scripting, that's pretty much the only way.XSLT 2.0 defines a way to create multiple documents, and defines storage for temporary trees, both of which you need for that. However, Xalan is only an XSLT 1.0 processor. You'd need SAXON or AltovaXML if you are to use XSLT 2.0.Just in case you could use it, I'm not sure how to do this in XSLT 2.0 since I've never done it myself. I just know it's possible based on what I've read. Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.