Ok, I am posting my first question, even if I use the site diligently. I have been trying to get a solution for this in the last two days without success. Using some answers to similar questions on this site ( this , this , this , this and many, many others), I was able to make some progress, but the full (and correct!) Solution still runs away.
I have existing XML (file1.xml) that I have to update based on the other that I generate (file2.xml): the contents of file2 must be included in file1, observing some rules that I will specify later (the contents of the files have been simplified to display only relevant items):
file1.xml
<?xml version="1.0" encoding="UTF-8"?> <list> <decade lastyear="2012" firstyear="2011"> <year value="2012"> <issue year="2012" number="242" /> <issue year="2012" number="241" /> <issue year="2012" number="240" /> </year> <year value="2011"> <issue year="2011" number="238" /> <issue year="2011" number="237" /> <issue year="2011" number="236" /> <issue year="2011" number="235" /> </year> </decade> <decade lastyear="2010" firstyear="2001"> <year value="2010"> <issue year="2010" number="234" /> <issue year="2010" number="233" /> <issue year="2010" number="232" /> <issue year="2010" number="231" /> <issue year="2010" number="230" /> </year> <year value="2009"> <issue year="2009" number="229" /> <issue year="2009" number="228" /> <issue year="2009" number="227" /> <issue year="2009" number="226" /> <issue year="2009" number="225" /> </year> ... </decade> </list>
file2.xml
<?xml version="1.0" encoding="UTF-8"?> <issue year="2013" number="245" /> ...
As already mentioned, the contents of file2 must be inserted into file1 subject to certain rules:
- If the year of release does not exist in file1 (i.e., when you insert the first problem of the year), it must be created (already completed)
- a new problem should be inserted in the corresponding year (already done)
- The decade should be updated to reflect the last year entered (problems with that!)
- The question element must be ordered in descending order by year and .
- If the year of issue is a new decade, it must be created along with the corresponding child year and issue.
- In the resulting document, all elements should be ordered in descending order: decade (lastyear), year (value) and issue number (year and number)
I am using Saxon-HE 9.4.0.6, and the xsl that I have done so far is:
XSL
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0"> <xsl:output method="xml" omit-xml-declaration="yes" indent="no" encoding="UTF-8"/> <xsl:variable name="up" select="document('../test/ExcelStory/file2.xml')"/> <xsl:variable name="year" select="$up/issue/@year" /> <xsl:template match="@* | node()" > <xsl:copy> <xsl:apply-templates select="@*|node()"> <xsl:sort select="//issue/@year" /> </xsl:apply-templates> </xsl:copy> </xsl:template> <xsl:template match="decade" > <xsl:copy> <xsl:apply-templates select="* | @*"/> <xsl:choose> <xsl:when test="year[1]/@value lt $year"> <year value="{$year}"/> </xsl:when> </xsl:choose> </xsl:copy> </xsl:template> <xsl:template match="year[@value=$year]"> <xsl:copy> <xsl:apply-templates select="* | @*"/> <xsl:apply-templates select="$up/*" /> </xsl:copy> </xsl:template> </xsl:stylesheet>
This stylesheet assumes that the contents of file1.xml are already ordered when reading (in this case).
I am wondering if I have to do more than one pass, using the βmodeβ, to first create a decade according to the year (if necessary) and then insert the year into the correct decade (on the second pass?), Then insert the questions into the correct year (third pass?) and finally reorder all elements (even another pass?) or if all the necessary processing can be performed more efficiently (one or two passes). Mr. Michael Kay suggested using xsl: for-each elsewhere for this kind of processing, but I donβt know if it can fit (easier?) In this case.
Even though this question may seem similar to some others in stackoverflow, I think there is some additional complexity that forces it to read (and maybe answers, hopefully!).
I would be grateful if you could give some ideas on how to proceed, or if you can point me to additional resources.