XSLT: Как получить имена файлов из определенного каталога? - PullRequest
15 голосов
/ 09 марта 2009

Есть ли в XSLT функция, которая может взять путь к каталогу и вернуть все файлы в нем ??

У меня есть XML-файл, теперь читается как это

<filelist>
    <file>fileA.xml</file>
    <file>fileB.xml</file>
</filelist>

Теперь есть каталог с именем dir, в котором есть файлы fileX.xml, fileY.xml и куча других XML-файлов. Я хочу добавить эти файлы в оригинальный XML-файл, чтобы я мог получить:

<filelist>
    <file>fileA.xml</file>
    <file>fileB.xml</file>
    <file>fileX.xml</file>
    <file>fileY.xml</file>
    .... <!-- other files -->
</filelist>

Есть ли способ XSLT сделать это ?? что-то, что берет в корень dir, и может перебирать все файлы в нем ?? И тогда я мог бы просто назвать что-то вроде:

<xsl:element name = file >
     <xsl:copy> <!--whatever file name--> <xsl:copy>
</xsl:element>0

[Edit-решение]

все ответы были очень полезны. Я закончил тем, что нашел внешнее решение (используя саксонский). Я подумал, что другим людям может быть полезно опубликовать мое решение здесь, хотя оно очень специфично для моей собственной ситуации.

Я использую Ant для создания веб-приложения на Java, и мне нужно перевести некоторые xml-файлы перед развертыванием. Поэтому я использовал задачу xslt для выполнения этой задачи, добавив "saxon9.jar" в путь к классам. И в моем файле xsl я просто сделал что-то вроде этого:

<xsl:for-each select="collection('../dir/?select=*.xml')" >
     <xsl:element name='file'>
        <xsl:value-of select="tokenize(document-uri(.), '/')[last()]"/>
     </xsl:element>
</xsl:for-each>

Ответы [ 4 ]

4 голосов
/ 09 марта 2009

XSLT не имеет ничего встроенного для этой задачи. XSLT - это язык преобразования - для динамического вывода обычно требуется преобразование source , которое уже содержит все (только в другой форме) & ndash; Вы не можете создавать XML из ничего.

Три способа решения этой проблемы:

  1. Сборка XML на языке программирования без использования XSLT. Это самый простой способ получить желаемый результат.
  2. Создайте таблицу стилей XSL, которая принимает параметр, поместите (предварительно созданный) список файлов с разделителями в этот параметр, позвольте XSLT обрабатывать строку и создавать из нее XML. Это также включает в себя внешнюю обработку, в основном это вариант 1. плюс вам нужно написать таблицу стилей XSL, которая выполняет обработку строк (что-то, к чему XSL не был привязан)
  3. Используйте функции расширения и выполняйте обработку каталогов из XSL. Пример того, как начать, можно найти в моем ответе на этот вопрос . Это не очень переносимо, поскольку функции расширения зависят от платформы.

Это сводится к этому:

  • Вам понадобится помощь от внешнего языка программирования
  • Вам абсолютно не нужно XSLT действительно выполняет задачу, поскольку вывод XML - это все, что вам нужно, и преобразование не требуется.

Ergo: не используйте XSL для этого.

1 голос
/ 09 января 2016

Вопросу шесть лет, и он ответил. Просто добавлю мои 2 цента для тех, кто снова приземлится здесь.

Мне нужен файл XML, представляющий имена файлов в каталоге. Я сделал это тремя способами:

  1. Документ XSLT 2.0 (), как другие указали в этой теме. Недостатком является производительность, так как он читает файл в парсер dom, когда все, что вам действительно нужно, это имя. Также, как указал LarsH в комментариях OP, это работает только с действительными файлами XML. Если в рекурсе есть файл не-xml или неправильно сформированный xml, он прервет преобразование.

  2. Инструмент xmlstarlet с командой xmlstarlet ls > filenames.xml

  3. Придуманный мной грубый сценарий bash (его можно оптимизировать):

DIRECTORY=$1
RESULTFILE=$2

# put the directory listing into a temp file
# modify the ls command for your needs
ls -A1 $DIRECTORY > /tmp/zFiles.txt

# remove detritus and wrap the lines in <file> elements
sed -i -e's/^[^$]*$/   <file filename="&"\/>/' /tmp/zFiles.txt

# build the file
echo '<?xml version="1.0" encoding="UTF-8"?>' > $RESULTFILE
echo "<files>" >> $RESULTFILE
cat /tmp/zFiles.txt >> $RESULTFILE
echo "</files>" >> $RESULTFILE

Я давно использовал скрипт bash, но теперь я использую исключительно метод xmlstarlet. Полученный в результате файл старлета содержит определенные атрибуты файла, такие как права доступа и даты, я считаю это полезным.

1 голос
/ 09 марта 2009

Вы не можете сделать это в родном XSLT, но различные реализации позволяют добавлять расширения к функциональности.

Например, в C # вы можете добавить пользовательский URN:

 <xsl:stylesheet {snipped the usual xmlns stuff}
    xmlns:user="urn:user" >

затем используйте функции внутри "пользователя"

  <xsl:value-of select="user:getdirectory( @mydir )" />

в C # вы связываете "пользователя" с классом C #:

 XSLThelper xslthelper      = new XSLThelper( );  // your class here
 xslArgs.AddExtensionObject( "urn:user", xslthelper );

и ваш класс определяет функцию "getdirectory":

public class XSLThelper
{
public string getdirectory(System.Xml.XPath.XPathNavigator xml, string strXPath, string strNULL)
{
       //blah
    }
}

Огромное количество домашней работы осталось здесь! MSDN Resource

0 голосов
/ 09 марта 2009

Вы должны иметь возможность использовать функцию document () для чтения XML-файлов. Однако я не уверен, насколько хорошо она поддерживается в различных механизмах XSLT.

Это хороший пример , показывающий, как он используется.

Но это не решает проблему чтения имен файлов из каталога. Другой ответ дает способ сделать это с этой стороны.

...