XSL 2.0 Transform XML files while preserving folder structure

纵饮孤独 提交于 2019-12-11 04:17:54

问题


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.


回答1:


(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.




回答2:


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.



来源:https://stackoverflow.com/questions/17221566/xsl-2-0-transform-xml-files-while-preserving-folder-structure

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!