shanmugharaj
shanmugharaj

Reputation: 3924

How to get all the files from a directory in xslt

I have a requirement to merge multiple xml files in to a single file. I achieved this by xsl transform. My xslt file is

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                exclude-result-prefixes="msxsl"
                xmlns:Utils="Utils:Helper">

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

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="assemblies">
    <xsl:copy>
      <xsl:apply-templates select="*"/>
      <xsl:apply-templates select="document('AdminService.xml')/reflection/assemblies/*" />
      <xsl:apply-templates select="document('Helpers.xml')/reflection/assemblies/*" />
      <!--<xsl:value-of select="Utils:GetFiles()"/>-->
    </xsl:copy>
  </xsl:template>

  <xsl:template match="apis">
    <xsl:copy>
      <xsl:apply-templates select="*"/>
      <xsl:apply-templates select="document('AdminService.xml')/reflection/apis/*" />
      <xsl:apply-templates select="document('Helpers.xml')/reflection/assemblies/*" />
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

My C# function is

var xslt = new XslCompiledTransform();
            xslt.Load("XmlMerger.xslt", new XsltSettings { EnableDocumentFunction = true, EnableScript = true}, null);


using (var writer = File.CreateText("XmlDocs\\result.xml"))
 {
                xslt.Transform(@"EmployeeService.xml", arguments, writer);
 }

In this three xml files EmployeeService, AdminService, Helpers are merged into a single file results.xml. This is working fine for me.

Now the calling of the xml files is static

<xsl:apply-templates select="document('AdminService.xml')/reflection/assemblies/*" />
 <xsl:apply-templates select="document('Helpers.xml')/reflection/assemblies/*" />.

I need to include all the xml files in a directory. Currently i tried by calling C# function in this xslt file by passing string like

 public string GetFiles()
        {
            return "<xsl:apply-templates select=\"document(\'Helpers.xml\')/reflection/assemblies/*\" />";

            //return "Helpers.xml";
        }

Note: Just for example i included only one file. Here I am trying to build that string pass it to the xslt file

<xsl:value-of select="Utils:GetFiles()"/>

But in the results its coming as plain text. How to escape this and tell its a template or how to dynamically include all the files from a directory ?

Upvotes: 1

Views: 1226

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167696

If you want to process an XML document in XSLT with XslCompiledTransform then you need to pass in an XPathNavigator from your C# code, if you want to process a directory of XML documents then you need to pass in an array of XPathNavigator objects. So you can write a method

    public XPathNavigator[] GetDocuments(string directory)
    {
        return Directory.EnumerateFiles(directory, "*.xml").Select(file => new XPathDocument(file).CreateNavigator()).ToArray();
    }

in a sample class MyHelperClass, instantiate that class in your C# code and pass it as an extension to the Transform call:

        XslCompiledTransform xsltProc = new XslCompiledTransform();
        xsltProc.Load("XSLTFile1.xslt");

        XsltArgumentList xsltArgs = new XsltArgumentList();
        xsltArgs.AddExtensionObject("http://example.com/mf", new MyHelperClass());

        xsltProc.Transform("input.xml", xsltArgs, Console.Out);

Then in your XSLT use e.g.

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  xmlns:mf="http://example.com/mf"
  exclude-result-prefixes="msxsl mf"
>

and then you can process e.g.

<xsl:apply-templates select="mf:GetDocuments('someDirectoryName')/root/foo/bar"/>

to process all bar elements found in the XML documents in the directory.

Upvotes: 2

Related Questions