1

I have a directory structure like this:

-TopFolder
 --ChildFolder1/file.xml
 --ChildFolder2/file.xml
 --ChildFolder3/file.xml

I'd like to navigate each child folder, apply my xslt stylesheet to file.xml, and output "file.html" in each folder. I've looked at collections() and some other things but I'm not quite sure which approach to take. Is this possible with XSLT 2.0?

Cheers

user3653270
  • 146
  • 1
  • 7
  • 1
    You don’t need XSL 2.0, you can just tell your processor to run the stylesheet on each XML file separately. What command are you using to run the transformation? – Buck Doyle May 19 '14 at 15:39
  • Well, I'm actually using an Eclipse XSLT plugin, which does accept transformation parameters (I believe these would behave as if you were running directly from the command line). I was thinking (perhaps naively) that I could collections() to recursively get the list of all the xml files and then apply the stylesheet to them, but maybe that is overkill? If there is a simple command line parameter to do this that would be wonderful. The other thing I should have mentioned is that there are > 100 child folders, thus the need for an approach to recursive processing. – user3653270 May 19 '14 at 15:44
  • I’ve never used that so I won’t be much help, but I do think it would be overkill. If each source document should produce one output document and there is no interaction between them, better to keep your stylesheet simple and not operate on multiple documents simultaneously. – Buck Doyle May 19 '14 at 15:48
  • What XSLT 2.0 processor are you using? – Daniel Haley May 19 '14 at 18:05

1 Answers1

1

Using Saxon, you can add this template rule to your stylesheet:

<xsl:template name="main">
  <xsl:for-each select="collection('.?select=*.xml;recurse=yes')">
    <xsl:result-document href="out/{tokenize(document-uri(.), '/')[last()]">
      <xsl:apply-templates select="."/>
    </xsl:result-document>
  </xsl:for-each>
</xsl:template>

and then invoke it supplying -it:main instead of a source document. Of course you may want to make adjustments to the way in which you supply the input and output directories.

Michael Kay
  • 138,236
  • 10
  • 76
  • 143
  • Thank you Michael. I did try this and now I have an error Invalid syntax for relative URI: Illegal character in path at index 81: out/file:%20C:%20Users%20me%20workarea%20TopFolder%20ChildFolder1%20 ml[last()] I wonder if somehow it thinks there are spaces in the output path even thought there are none? – user3653270 May 19 '14 at 20:37
  • Well, I guess it would be an interesting exercise for me to try and construct code that has that effect, but I'd probably be way off the mark. In the meantime I'll leave the debugging to those with access to the code. – Michael Kay May 19 '14 at 22:54
  • Micheal - thank you. You gave me just enough to figure out the rest, which of course required a bit of customization. – user3653270 May 20 '14 at 19:11
  • @user3653270, Michael, in something unrelated, I'm getting the same error message, and right now Google's one and only hit for _"Invalid syntax for relative URI"_ is this very thread. Did you ever figure out what was causing this? I'm baffled. – Eiríkr Útlendi Feb 23 '21 at 23:25
  • Derp -- I figured it out! Realized that the generated string included whitespace, which is disallowed for URI strings -- see also https://stackoverflow.com/questions/1547899/which-characters-make-a-url-invalid. The fix (for me, anyway) was to wrap the generated string in `encode-for-uri()`, and use that value for the `href` attribute in the `xsl:result-document` element. Cheers! – Eiríkr Útlendi Feb 23 '21 at 23:33