Kategorie szkoleń | Egzaminy | Kontakt
  • 1
  • 0
  • 74
Zaloguj się aby zadać pytanie
Pokrewne

Odpowiedź (1)

  • 0

Głównym celem transformat XSLT jest przetworzenie zawartości plików XML do innej postaci tekstowej (np. zwykłego tekstu, innego XML, HTML lub XHTML). Czyli transformata XSLT oczekuje "na wejściu" danych XML.

Odwoływanie się do zawartości katalogów nie jest typowym zadaniem dla transformat. Jeśli potrzebujemy takiej funkcjonalności, to najprościej użyć jakiegoś języka programowania. Takie rozwiązanie będzie bardziej eleganckie (używamy narzędzi zgodnie z ich przeznaczeniem).

Nie oznacza to, że nie da się tego zrobić za pomocą XSLT...

Będziemy potrzebować procesora XSLT w wersji co najmniej 2.0 (może być np. Saxon-HE)

Taka transformata może wtedy przedstawiać się następująco:

<?xml version="1.0" ?>
<xsl:stylesheet version="2.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" />

  <xsl:template match="/">
    <xsl:result-document href="output.xml" indent="yes">
      <xsl:variable name="path"
                    select="'file:///C:/somedir/test/'" />
      <xsl:variable name="filter" select="'?select=*.xml'" />
      <xsl:variable name="uris" select="concat($path, $filter)" />
      <files>
        <xsl:for-each select="collection($uris)">
          <file><xsl:value-of select="tokenize(document-uri(.), '/')[last()]" /></file>
        </xsl:for-each>
      </files>
    </xsl:result-document>
  </xsl:template>

</xsl:stylesheet>

Jeśli w filtrze plików chcemy użyć wyrażeń regularnych, to transformatę trzeba trochę zmodyfikować:

<?xml version="1.0" ?>
<xsl:stylesheet version="2.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" />

  <xsl:template match="/">
    <xsl:result-document href="output.xml" indent="yes">
      <xsl:variable name="path"
                    select="'file:///somedir/test/'" />
      <xsl:variable name="filter" select="'?select=*.(xml|xsl)'" />
      <xsl:variable name="uris" select="iri-to-uri(concat($path, $filter))" />
      <files>
        <xsl:for-each select="collection($uris)">
          <file><xsl:value-of select="tokenize(document-uri(.), '/')[last()]" /></file>
        </xsl:for-each>
      </files>
    </xsl:result-document>
  </xsl:template>

</xsl:stylesheet>

Przedstawione powyżej rozwiązanie nie jest uniwersalne - zawiedzie, gdy w katalogu znajdą się pliki binarne. Wyjściem mogłoby być zastąpienie funkcji collection() przez uri-collection(), ale ta jest dostępna dopiero w XPath 3.0.

  • Odpowiedział
  • @ | 12.12.2015
  • TRENER MODERATOR ALTKOM AKADEMII