tags:

views:

134

answers:

1

I have a directory of XML files... for example:

   result.xml
   result2.xml
   result3.xml
   resultNth.xml (because there is an unknown amount of files)

the schema in each result file would be the same essentially

    <Succeeded>
          <someStrongXMLObject>

          </someStrongXMLObject>
    </Succeeded>

My Question is - can I include 1 additional XML File called results.xml in that directory... and an XSL file that will format the results...

I want to create a summary from all the result files... so that data from all these files will be included in the summary.

Is this possible? Without using any C# - just standard XML, XSLT?

Update

I don't expect a solution, just a nod, yes its possible, or a resounding no.. I need to implement some C#. Also I would like the directory structure to be YYYY/MM/DD - so that I can have summary XML files, that will recurse thought sub directories... and create monthly and annual summaries.

+2  A: 

Yes, it is definitely possible.

How easy it is will depend on how reliable your filename and folder name patters are. You can use the document() function to check for the presence of a result file. Use recursion to keep looking for the next sequentially named file until you reach the end.

From your example filenames, the following XSLT could be used:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="/">
        <summary>
            <xsl:call-template name="getResults">
                <!--First call, use empty index -->
                <xsl:with-param name="index" />
            </xsl:call-template>
        </summary>
    </xsl:template>

    <xsl:template name="getResults">
        <xsl:param name="index" />
        <xsl:variable name="filename">
            <xsl:choose>
                <xsl:when test="$index =''">
                    <xsl:value-of select="concat('result', '.xml')" />
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="concat('result', $index, '.xml')" />
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <xsl:choose>
            <!--Check for the presence of the file -->
            <xsl:when test="document($filename)">
                <!--If it exists, then output something from the document-->
                <Result>
                    <xsl:attribute name="href">
                        <xsl:value-of select="$filename" />
                    </xsl:attribute>
                    <xsl:copy-of select="document($filename)/Succeeded" />
                </Result>
                <!--Then, call the function with a new index value to look for the next file-->
                <xsl:call-template name="getResults">
                    <xsl:with-param name="index">
                        <xsl:choose>
                            <!--If empty index, start at 1 -->
                            <xsl:when test="$index=''">
                                <xsl:value-of select="1" />
                            </xsl:when>
                            <xsl:otherwise>
                                <!--Add 1 to the previous index value -->
                                <xsl:value-of select="number($index+1)" />
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:with-param>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:comment>Done looking for Results. Found <xsl:value-of select="number($index)" /> files.</xsl:comment>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

I ran it with 3 result documents in the same folder as the XSLT(i.e. result.xml, result1.xml, result2.xml) and produced the following output:

<?xml version="1.0" encoding="utf-8"?>
<summary>
<Result href="result.xml">
<Succeeded>
        <someStrongXMLObject>

        </someStrongXMLObject>
    </Succeeded>
</Result>
<Result href="result1.xml">
<Succeeded>
        <someStrongXMLObject>

        </someStrongXMLObject>
    </Succeeded>
</Result>
<Result href="result2.xml">
<Succeeded>
        <someStrongXMLObject>

        </someStrongXMLObject>
    </Succeeded>
</Result>
<!--Done looking for Results. Found 3 files.-->
</summary>
Mads Hansen
Depending on how deep/long the directory structure is, recursion can hit a hard limit. Not overly likely, but possible. One way around that would be a iterative/hybrid approach - a helper XML file with 100 or so nodes that you can iterate over (`<xsl:for-each select="100nodes">`). Once you hit 100, you can take one recursive step and do it again. Just an idea.
Tomalak