Search code examples
xmlxsltfilelist

Select from within a fileliste of xml


I use xslt 2.0 to transform xml data to xml files. I created xsl to find all filenames in a folder, which worked fine:

filenames.xml

<?xml version="1.0" encoding="UTF-8"?>
<filelist>
   <file>birds2014.xml</file>
   <file>birds2013.xml</file>
</filelist>

Then I created a xsl to search within the xml-files to select all the names of the birds which are located in the tag <spbird> in all documents.

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

<xsl:template match="*">
        <xsl:apply-templates/> 
        <xsl:variable name="files" select="document('filelist.xml')/filelist/file"/>
            <xsl:element name="birdname">
                <xsl:for-each select="document($files)">    
                    <xsl:value-of select="//spbird">
                    </xsl:value-of>
                </xsl:for-each>
            </xsl:element>  
    </xsl:template>

Result:

<birdname>Papagei Wellensittich Pfau</birdname>
<birdname>Papagei Wellensittich Pfau</birdname>
<birdname>Papagei Wellensittich Pfau</birdname>
<birdname>Papagei Wellensittich Pfau</birdname>
<birdname>Papagei Wellensittich Pfau</birdname>
<birdname>Papagei Wellensittich Pfau</birdname>
<birdname>Papagei Wellensittich Pfau</birdname>
<birdname>Papagei Wellensittich Pfau</birdname>
<birdname>Papagei Wellensittich Pfau</birdname>

Expected:

<birdname>Papagei</birdname>
<birdname>Wellensittich</birdname>
<birdname>Pfau</birdname>

Can anyone help?

Edit I changed the

 <xsl:template match="*">

to

   <xsl:template match="/">

which resolves the issue of the same result showing up 9 times (where did this number came from).

Now with your help the result is:

<birdname>Papagei Wellensittich</birdname>
<birdname>Pfau</birdname>

Pfau is the bird in the second xml file. Only problem is, that document() seems to do a for-each on it's own. So I do not get all the birds listed seperately in a birdname tag..

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

<xsl:template match="*">
        <xsl:apply-templates/> 
        <xsl:variable name="files" select="document('filelist.xml')/filelist/file"/>

                <xsl:for-each select="document($files)">   
                       <birdname> 
                         <xsl:value-of select="//spbird">
                       </birdname>
                    </xsl:value-of>
                </xsl:for-each>
            </xsl:element>  
    </xsl:template>

Solution

  • Try putting your element inside of the xsl:for-each...

    <xsl:for-each select="document($files)">    
        <birdname>
            <xsl:value-of select="//spbird"/>            
        </birdname>
    </xsl:for-each>
    

    Note: Unless you're trying to dynamically build the element name, there's no reason to use xsl:element.

    Edit

    In XSLT 2.0, xsl:value-of will give you every value of spbird. Instead of a xsl:for-each on the document, you should do the for-each on the spbird. Try changing your xsl:for-each to the example below. If that doesn't work, please add an example of the bird files to your question.

    <xsl:for-each select="document($files)//spbird">    
        <birdname>
            <xsl:value-of select="."/>            
        </birdname>
    </xsl:for-each>