XSL read file names from a folder

0

I have the following file structure in a folder:

-PASTA_XYZ
  - file1.xml
  - file2.xml
  - file3.xml
  - index.xml

I would like the index.xml file to return the name of the files in this folder, but I am having difficulty with the FOR-EACH statement:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

    <list>
        <xsl:for-each select="collection(.?select=*.xml')">
            a
        </xsl:for-each>
    </list>
</xsl:stylesheet>

When I run the file index.xml in the browser , only "a" is printed on the screen, the expected one would print "aaa", since there are 3 files, FOR-EACH should run 3 times.

    
asked by anonymous 15.05.2014 / 17:35

1 answer

1

The behavior of the browser is expected . You included an XML document that contains the <?xml-stylesheet...> processing instruction, so the browser will not show the XML structure as it would with documents that do not have this statement (it hands the responsibility to the XSLT processor). But he does not find the file, and having no style rules for formatting the tags, prints them using default styles by displaying on the screen the only text node that is available: a .

Simply loading an XSLT into the browser will not make it run because the browser does not know if the XML document in question is an XSL ! For the browser, you simply loaded any XML. You must use the <?xml-stylesheet...> processing instruction to enter the URL of an XSLT so that the browser can attempt to interpret it.

Your XML document has one of these, but it refers to a document that does not exist in the folder where you reported your files:

<?xml-stylesheet type="text/xsl" href="test.xsl"?>

This statement means that your document ( index.xml ?) is being treated by the browser as a source document for test.xsl .

I'll assume your index.xml document is actually another, and the one you posted is actually your text.xsl . In this case, you must remove the processing instruction and copy it to your index.xml :

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<raiz>
    <mensagem>Hello, world</mensagem>
</raiz>

Now the browser will treat the code you posted (assuming it is in test.xsl ) as XSLT. You load index.xml , and the browser processes test.xsl to transform your document.

And then it fails. For several reasons.

The first is that you need to have at least one template in an XSLT style sheet. The template will match those in the XML tree of your source document using XPath. There are already some templates built in, ready, but if you want to produce something different you need to create one.

This will depend on the structure of your source document. In the example I posted, you could write templates to match / (root element), raiz , mensagem . To quickly fix your XSLT document, and as I do not know the actual structure of your source document, we can include your code inside a template that matches / :

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

    <xsl:template match="/">
        <list>
            <xsl:for-each select="collection('.?select=*.xml')">
                a
            </xsl:for-each>
        </list>
    </xsl:template>

</xsl:stylesheet>

This would be enough to fix your XSLT. Now you can load index.xml and the browser's XSLT processor will process the template, generating a list. But it will not work because almost certainly your browser does not support XSLT 2.0 . And it's no use changing the version because the collection() function only exists in XSLT 2.0.

There are several alternatives though. You can get the list of files from somewhere else, from the source file itself, from another external file, and use the document() function that exists in XSLT 1.0. But the ideal is you study a little more about XPath and XSLT before, as the use of these functions is not so trivial.

If your source file ( index.xml ) has a section containing the file names you need to upload, for example:

<raiz>
    ...
    <arquivos>
        <arquivo>file1.xml</arquivo>
        <arquivo>file2.xml</arquivo>
        <arquivo>file3.xml</arquivo>
    </arquivos>
</raiz>

You could use the following statement to print a list containing the root element name of each:

<list>
    <xsl:for-each select="document(//arquivo)">
        <li><xsl:value-of select="name(./*)"/></li>
    </xsl:for-each>
</list>

This funciona in XSLT 1.0. Then you can change version to 1.0 and test in any modern browser.

    
16.05.2014 / 01:46