Question

I have the following XSL to transform a bunch of XML files from one format to another. The transformation is working fine though I have two issues unresolved so far:

1) First when transforming the files I need to adjust my parameter in the style sheet to target only files that have names longer than 7 characters;

2) Secondly, I need to be able to transform all the files while preserving the folder structure of the source files. I was wondering if there is way to preserve the same folder structure like from the source folder. All the files are located in folders named based on the alphabet like : A, B, C, D, F .... So I need to transform all files in folder A and put them in a new folder named A. The files are also named by alphabetical order.

Here is my style sheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:ditaarch="http://dita.oasis-open.org/architecture/2005/">

<!-- This adds DOCTYPE declaration -->
<xsl:output method="xml" doctype-public="-//OASIS//DTD DITA Glossary//EN"
doctype-system="glossary.dtd" omit-xml-declaration="no" indent="yes"/>

<!-- The below line ensures that all empty space and carriage returns are removed from the title element producing proper file names -->
<xsl:strip-space elements="title"/>

<xsl:param name="files" select="collection('../DITA/B/?select=*.dita;recurse=yes')"/>

<!-- <xsl:variable name="filename" select="concat($files,position(),'topic')" />-->

<xsl:template match="node()">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">

<xsl:for-each select="$files//topic">
<xsl:if test="string-length(files) &gt; 10">
<!-- not working, the purpose is to drop all the files whose name length is less than two letters -->

<xsl:value-of select="text()" disable-output-escaping="yes"/>
</xsl:if>
<xsl:result-document href="outputDITANEW/B/{title/text()|title/b/text()}.dita">
<glossentry id="{concat('test', generate-id())}">
<glossterm id="{concat('test_title', generate-id())}">
<xsl:value-of select="title"/>
</glossterm>
<glossdef>
<xsl:for-each select="body">
<xsl:apply-templates/>
</xsl:for-each>
</glossdef>
</glossentry>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Thanks.

Was it helpful?

Solution

(a) the select=*.dita is actually a regular expression masquerading as a glob, and you should be able to use something like select=[A-Za-z0-9]{7,}.dita to be more selective.

(b) the function document-uri() applied to a file returns the URI of the input file if known, and from this you should be able to construct the require output file name.

OTHER TIPS

If you are using Oxygen and you have the DITA framework installed, then you have the library frameworks/dita/DITA/plugins/net.sourceforge.dita4publishers.common.xslt/xsl/lib/relpath_util.xsl

This library provides functions for manipulating URLs and makes it easy to do things like get the parent path of the input document, calculate relative paths, and so on. So should be just what you need for constructing your result URLs.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top