XSL 2.0 Преобразование файлов XML с сохранением структуры папок
У меня есть следующий XSL для преобразования нескольких файлов XML из одного формата в другой. Преобразование работает нормально, хотя у меня есть две нерешенные проблемы:
1) Сначала при преобразовании файлов мне нужно настроить параметры в таблице стилей так, чтобы они предназначались только для файлов, имена которых длиннее 7 символов;
2) Во-вторых, мне нужно иметь возможность преобразовывать все файлы, сохраняя структуру папок исходных файлов. Мне было интересно, если есть способ сохранить ту же структуру папок, как из исходной папки. Все файлы расположены в папках, названных по алфавиту, например: A, B, C, D, F .... Поэтому мне нужно преобразовать все файлы в папке A и поместить их в новую папку с именем A. также назван в алфавитном порядке.
Вот моя таблица стилей:
<?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) > 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>
Благодарю.
2 ответа
(a) select=*.dita на самом деле является регулярным выражением, маскирующимся под глобус, и вы должны иметь возможность использовать что-то вроде select=[A-Za-z0-9]{7,}.dita
быть более избирательным.
(б) функция document-uri()
применительно к файлу возвращает URI входного файла, если он известен, и из этого вы должны иметь возможность создать требуемое имя выходного файла.
Если вы используете Oxygen и у вас установлена платформа DITA, то у вас есть библиотеки frameworks/dita/DITA/plugins/net.sourceforge.dita4publishers.common.xslt/xsl/lib/relpath_util.xsl
Эта библиотека предоставляет функции для манипулирования URL-адресами и позволяет легко делать такие вещи, как получение родительского пути во входном документе, вычисление относительных путей и так далее. Так что должно быть именно то, что вам нужно для построения ваших URL результатов.