XSLT: Как получить имена файлов из определенного каталога?

Здесь предложение, так как я использую отсортированный массив, в моем случае в порядке возрастания, потому что это кажется более «естественным» (использование в порядке убывания почти ничего не меняет).

Для сортировки первых значений 'k' я использую qsort из stdlib и функцию comp для выполнения необходимых сравнений.

Основная функция insert , поскольку массив отсортирован, можно сначала найти, куда вставить новый элемент со сложностью log2 (k), но после этого может понадобиться переместить уже представить элементы на 1 позицию, чтобы создать место для нового элемента, поэтому я предпочел выполнить поиск и перемещение одновременно.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>

/* for qsort */
int comp(const void * p1, const void * p2)
{
  return (*((int *) p1) - *((int *) p2));
}

/* insert v in arr having sz elts */
void insert(int * arr, int v, int sz)
{
  if (v > arr[0]) {
    /* search and move elts to let a hole for the new elt */
    for (int i = 1; i != sz; ++i) {
      if (v <= arr[i]) {
        /* place it in the hole */
        arr[i - 1] = v;
        return;
      }
      arr[i - 1] = arr[i];
    }

    /* v is the greater value */
    arr[sz - 1] = v;
  }
}

int main(int argc, char *argv[])
{
  int k;
  FILE * iFile;
  int * arr;

  if ((argc != 3) || (sscanf(argv[1], "%d", &k) != 1))
    fprintf(stderr, "Usage: %s <number of value> <file>\n", *argv);
  else if (k < 1)
    fprintf(stderr, "<number of value> must be greater than 0\n");
  else if ((iFile = fopen(argv[2], "r")) == NULL)
    fprintf(stderr, "cannot open '%s'\n", argv[2]);
  else if ((arr = malloc(k * sizeof(int))) == NULL)
    fprintf(stderr, "cannot allocate an array of %d in\n", k);
  else {
    /* read first 'k' values */
    int i;

    for (i = 0; i != k; ++i) {
      if (fscanf(iFile, "%d", &arr[i]) != 1) {
        fprintf(stderr, "invalid file or too few values in\n");
        fclose(iFile);
        return -1;
      }
    }

    /* sort them */
    qsort(arr, k, sizeof(int), comp);

    /* manage all the next values */
    int v;

    while (fscanf(iFile, "%d", &v) == 1)
      insert(arr, v, k);

    fclose(iFile);

    /* print result */
    for (i = 0; i != k; ++i)
      printf("%d ", arr[i]);
    putchar('\n');
    free(arr);
    return 0;
  }

  return -1;
}

Компиляция и выполнение:

pi@raspberrypi:/tmp $ gcc -pedantic -Wextra -Wall k.c
pi@raspberrypi:/tmp $ cat a.txt 
12 78 6 2 9 56 3 45 21 0 1 56 0
pi@raspberrypi:/tmp $ ./a.out 10 a.txt 
2 3 6 9 12 21 45 56 56 78 
pi@raspberrypi:/tmp $ ./a.out 3 a.txt 
56 56 78 
pi@raspberrypi:/tmp $ ./a.out 1 a.txt 
78 

Выполнение по valgrind :

pi@raspberrypi:/tmp $ valgrind ./a.out 10 a.txt 
==2217== Memcheck, a memory error detector
==2217== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2217== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==2217== Command: ./a.out 10 a.txt
==2217== 
2 3 6 9 12 21 45 56 56 78 
==2217== 
==2217== HEAP SUMMARY:
==2217==     in use at exit: 0 bytes in 0 blocks
==2217==   total heap usage: 4 allocs, 4 frees, 5,512 bytes allocated
==2217== 
==2217== All heap blocks were freed -- no leaks are possible
==2217== 
==2217== For counts of detected and suppressed errors, rerun with: -v
==2217== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
15
задан tomato 12 March 2009 в 19:23
поделиться

3 ответа

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

Этими тремя путями можно заняться проблемой:

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

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

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

Следовательно: Не используйте XSL для этого.

4
ответ дан 1 December 2019 в 05:16
поделиться

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

Например, в C# можно добавить определяемую пользователем УРНУ:

 <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
    }
}

Количество Hugh домашней работы оставлено здесь! Ресурс MSDN

1
ответ дан 1 December 2019 в 05:16
поделиться

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

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

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

0
ответ дан 1 December 2019 в 05:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: