Schema naam aanpassingen van QGis projectfiles via XSLT

Dankzij de dames en heren van NLExtract is het sinds vorig jaar mogelijk een Postgresql backup te krijgen van o.a. de BAG en de Top10nl kaarten. Via een restore heb je dan weer de meest actuele cartografische gegevens. Klein ongemak is dat bij de restore de databases in een apart schema worden gezet (‘bagactueel’ voor de BAG en ‘ttnl´ voor de top10nl), maar dat de QGis projectfiles die ik de afgelopen anderhalf jaar heb in elkaar geknutseld, een verwijzing bevatten naar het standaard ‘public’ schema.

Nu zijn de projectfiles van QGis gewoon XML, maar zoek-en vervang gaat niet. Gelukkig na een paar uurtjes knutselen had ik een XSLT file en een C# Windows Forms projectje dat in de gekozen folder, alle QGS-bestanden automatisch omzet en voorziet van \’NEW\’ in de naam.

Recursief door alle subfolders binnen die folder had ook nog gekund, maar veel projectfiles zal ik niet meer gebruiken, dus dat zou teveel inspanning zijn. Bovendien is het een eenmalige aanpassing, totdat NLExtract de schemanamen weer verandert. De code is:

<xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
  <xsl:template match="datasource">
     <xsl:variable name="apos">'</xsl:variable>
    <xsl:variable name="quote">"</xsl:variable>
    <xsl:copy>
      <xsl:choose>
      <xsl:when test="contains(text(), concat('dbname=', $apos, 'top10nl', $apos)) and not(contains(text(), concat($quote, 'ttnl', $quote, '.')))">
     
        <xsl:value-of select="substring-before(text(), 'table=')"/>
        <xsl:value-of select="concat('table=', $quote, 'ttnl', $quote, '.')"/>
        <xsl:value-of select="substring-after(text(), 'table=')"/>
      </xsl:when>
     <xsl:when test="contains(text(), concat('dbname=', $apos, 'bag', $apos)) and not(contains(text(), concat($quote, 'bagactueel', $quote, '.')))">
        <xsl:value-of select="substring-before(text(), 'table=')"/>
        <xsl:value-of select="concat('table=', $quote, 'bagactueel', $quote,  '.')"/>
        <xsl:value-of select="substring-after(text(), 'table=')"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="text()"/>  
    </xsl:otherwise>
      </xsl:choose>
      </xsl:copy>
   </xsl:template>
Het windows forms C# project bevat een button waarna je een folder selecteert. Vervolgens worden alle bestanden met qgs als extensie opgehaald en door de XSLT mangel gehaald.

private bool ConvertXML(string qgsfile)
        {
            try
            {
                string QGSXslt = @"CheckAddSchema.xslt";
                string resultQGSfile = Path.GetDirectoryName(qgsfile) + @"\\" + Path.GetFileNameWithoutExtension(qgsfile) + "New" + Path.GetExtension(qgsfile);
                // Create a writer for writing the transformed file.
                XmlWriter writer = XmlWriter.Create(resultQGSfile);
                // Create and load the transform with script execution enabled.
                XslCompiledTransform transform = new XslCompiledTransform();
                transform.Load(QGSXslt);
                XmlReaderSettings x = new XmlReaderSettings();
                x.DtdProcessing = DtdProcessing.Ignore;
                XmlReader readerQGSfile = XmlReader.Create(qgsfile, x);
                transform.Transform(readerQGSfile, writer);
                return true;
            }
            catch
            {
                return false;
            }
        }
        private void button2_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                string filePath = fbd.SelectedPath.ToString();
                textBox1.Text = filePath;
                string[] qgsfiles = Directory.GetFiles(filePath, "*.qgs");
                foreach (string file in qgsfiles)
                {
                    txtList.Text += "Start conversion: " + Path.GetFileName(file) + System.Environment.NewLine;
                    bool succes = ConvertXML(file);
                  
                    if (succes == true)
                    {
                        txtList.Text += "Converted " + Path.GetFileName(file) + System.Environment.NewLine;
                    }
                    else
                    {
                        txtList.Text += "Not converted " + Path.GetFileName(file) + System.Environment.NewLine;
                    }
                }
            }
        }