XSL read file names from a folder

Asked

Viewed 304 times

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 have difficulties in 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, is printed on the screen only "a", and the expected would be to print "aaa", since there are 3 files, and the FOR-EACH loop should be executed 3 times.

  • Welcome to the Sopt. Just to help you get used to our philosophy, which is different from a forum, take a look at pt.stackoverflow.com/help/behavior, especially 3rd. item. If not read yet, it would be good to take a look at [about], you win a medal. You can use [Edit] to leave your question in the way of a straight and clean question. Gradually you get used to it.

  • @bigown Grateful for the tips. I wonder if this is a standard welcome message or is there really something to be improved on my question.

  • Both :) improved for you. There is no rigid recommendation of what should be done in every detail, but what was most out of the standard that we adopted were texts that we appreciated (the important thing is the question itself) and if anyone can help, which is rhetoric, we are here to help. We tend to be very objective to be easier to help and to be useful to other people.

  • Perfect! Got it! Tks! :)

  • The browser will not interpret your document as an XSL. The only way to do this is by including a processing instruction <?xml-stylesheet...> in his source XML document with a reference to XSL. Your source document has XSLT but the browser will not interpret. It is simply printing the text node it contains a.

1 answer

1

The behavior of the browser is expected. You have included an XML document that contains the processing instruction <?xml-stylesheet...>, so the browser won’t show the XML structure as it would with documents that don’t have that instruction (it hands responsibility to the XSLT processor). But it does not find the file, and having no style rules to format the tags, prints them using default styles 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 need to use the processing instruction <?xml-stylesheet...> to inform the URL of an XSLT so that the browser can try 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 to be:

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

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

I will then assume that your document index.xml is actually another, and the one you posted is actually yours text.xsl. In this case, you should 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 handle the code you posted (assuming it is on test.xsl) as XSLT. You carry the index.xml, and the browser processes the test.xsl to transform your document.

And then it fails. For various reasons.

The first is that you need to have at least one template in an XSLT style sheet. The template will match the ones 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 since I don’t know the actual structure of your source document, we can include your code within 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 the index.xml and the browser’s XSLT processor will process the template, generating a list. But it won’t work because almost certainly your browser does not support XSLT 2.0. And no use changing the version because the function collection() only exists in XSLT 2.0.

There are several alternatives, however. You can take the list of files from elsewhere, from the source file itself, from another external file, and use the function document() that exists in XSLT 1.0. But ideally you should study a little more about Xpath and XSLT before, because the use of these functions is not so trivial.

If your source file (index.xml) had a section containing the names of the files 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 instruction below to print a list containing the root element name of each of them:

<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 the version for 1.0 and test in any modern browser.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.