GUI 6x jinak


Na první stranu
TOPlist
Cílem projektu bylo vyzkoušení tvorby GUI aplikací v nových zajímavých nástrojích, jež jsem se chystal naučit. Konkrétně šlo o následující:
  • Delphi 7 (CLX) - super výkonný RAD nástroj pro rychlou tvorbu výkonných aplikací pro MS Windows a při použití knihoven CLX i přenositelný do Kylixu 3 pro tvorbu Linux aplikací.
  • Java 1.4.1 - objektově orientovaný, distribuovaný, přenositelný, vícevláknový, interpretovaný programovací jazyk nezávislý na architektuře
  • Python/Tk 2.2.1 - beztypový interpretovaný objektově orientovaný programovací jazyk nezávislý na architektuře
  • Tcl/Tk 8.4a2 - interpretovaný jazyku nezávislý na architektuře. Je velmi jednoduchý, spíše podobný shellům, jeho výhody jsou především v různých speciálních rozšířeních. Nejznámějsí z nich je Tk, toolkit pro snadné a rychlé vyvíjení jednoduchých "okýnkových" aplikací.
  • Perl/Tk 5.6.1 - interpretační programovací jazyk určený převážně pro zpracování textových souborů, získávání informací z nich a následné podání výsledků nezávislý na architektuře
  • Ruby/Tk 1.7.2 - interpretační objektově orientovaný programovací jazyk nezávislý na architektuře
Hned na úvod musím uvést, že Delphi jsem nezkoušel, protože tenhle nástroj používám už 6 let a tedy ho dokonale znám. Legální licenci Delphi 7 mám k dispozici od září, kdy byla vydána sedmá verze tohoto perfektního nástroje. Aplikaci jsem v Delphi vytvářel, abych si vyzkoušel jak dlouho by mi tvorba takové aplikace trvala a dospěl jsem k času zhruba 15 minut (nejdéle jsem aplikaci vytvářel v Javě).

Konkrétně jsem se chtěl v nových prostředích naučit následující funkce:
  • načítání konfgurace z ini souboru, resp. vůber práce se soubory
  • vytváření GUI rozhraní
  • spouštění externích aplikací
  • vyvolávaní standardních dialogů (tady dialog pro otevření souboru)
To vše se mi nakonec podařilo. I když aplikace rozhodně nejsou optimalizovány, mohou být vodítkem pro vlastní pokusy.

K čemu vlastně aplikace slouží?

Při experimentech s XML a jejich transformacemi jsem narazil na klasickou potřebu takového jednoduchého klienta, který bude celou transformaci spouštět na kliknutí tlačítka místo vypisování příkazů v příkazovém řádku (i když F3 je taky řešení, ale ne tak elegantní a není na něm se co učit). Nebudu popisovat k čemu jsou vhodné XML soubory. Jenom uvedu, co jsem prováděl. Měl jsem XML soubory (jeden obsahoval příručku napsanou podle standardu DocBook, druhý definici databázové struktury podle standardu CARD a konečně třetí model tříd z CASE nástroje ArgoUML) a k nim XSL soubory s popisem transformačních stylů. Pomocí těchto stylů lze XML soubor transformovat do jiné podoby. V připadě souboru DocBook jsem prováděl transformaci do HMTL formátu. Soubor CARD jsem transformoval do SQL skriptu (sada CREATE ... a INSERT INTO příkazů). A konečně model jsem převáděl do HTML formátu elektronické dokumentace modelu. Všechny tři převody jsou velmi zajímavé a užitečné. Převod DocBook do HTML případně do PDF (informace o tomto projektu jsou na této stránce) slouží k publikování dokumentů (hlavně příruček) v elektronické (html) i tištěné (pdf) formě při používání pouze jediného zdroje (souboru), z něhož jsou tyto formy za pomocí stylů (xsl) a formátovacích objektů (fo) vytvářeny. Převod CARD (a nejenom) do SQL lze obecně použít pro generování SQL skriptů bez složitého programování jednoúčelových aplikací. XSL transformační soubor je obyčejný textový soubor napsaný v XSLT standardním jazyce. Obdobně lze např. převádět data pomocí XML mezi různými databázemi s různými odpovídajícími databázovými strukturami. A bez specializovaných nástrojů a drahých programů. Tohle je jeden ze stavebních kamenů e-business. Poslední převod může například sloužit k elektronickém publikování výstupů modelů objektové analýzy.

K transformaci jsem použil jeden z v současné době nejlepších nástrojů. A to SAXON. Konkrétně jeho instant verzi 6.5. Jde binární verzi pro použití ve Windows pro ty, kteří nemají Java knihovny. Syntaxe:

saxon -o výstupní_soubor xml_soubor xsl_soubor

Existuje i i java verze 7 tohoto nástroje. Ale potřebujete minimálně Java JRE 1.4 a vyšší (lepší je Java SDK 1.4 a vyšší). Tuto verzi jsem začal používat nedávno, takže ještě nemám upraven skript pro spouštění aplikace. Ovšem je to velmi snadné. Syntaxe se lehce změní na:

java.exe - cp . -jar saxon7.jar -o výstupní_soubor xml_soubor xsl_soubor


Vzhledu prográmku (tady v Tcl/Tk)


Upozornění: Vzhledem k šířce stránky jsou řádky výpisu zalamovány. Pokud si chcete kód stáhnout, je lepší použít přiložené zip soubory!

Společné testovací a konfigurační soubory jsou zde

Delphi

Zdrojový kód:
program PDSrunxslt;

uses
  QForms,
  MainForm in 'MainForm.pas' {MainFrm};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TMainFrm, MainFrm);
  Application.Run;
end.

unit MainForm;

interface

uses
  SysUtils, Types, Classes, Variants, QTypes, QGraphics, QControls, QForms,
  QDialogs, QStdCtrls, QButtons, Windows, Inifiles;

type
  TMainFrm = class(TForm)
    lblXml: TLabel;
    lblXsl: TLabel;
    lblOutput: TLabel;
    lblXslt: TLabel;
    edtXml: TEdit;
    edtXsl: TEdit;
    edtOutput: TEdit;
    edtXslt: TEdit;
    Button1: TButton;
    Button2: TButton;
    sbtnXml: TSpeedButton;
    sbtnXsl: TSpeedButton;
    sbtnOutput: TSpeedButton;
    sbtnXslt: TSpeedButton;
    fodlgOpen: TOpenDialog;
    procedure sbtnXmlClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormActivate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  MainFrm: TMainFrm;

implementation

{$R *.xfm}

procedure TMainFrm.sbtnXmlClick(Sender: TObject);
var
  sDesc: String;
  sDefaultExt, sFileName, sFilter, sTitle: String;
begin
// File open
  if Sender = sbtnXml then
  begin
    sDesc := 'edtXml';
    sDefaultExt := 'xml';
    sFileName := '*.xml';
    sFilter := 'XML files (*.xml)';
    sTitle := 'Find the XML source file';
  end;
  if Sender = sbtnXsl then
  begin
    sDesc := 'edtXsl';
    sDefaultExt := 'xsl';
    sFileName := '*.xsl';
    sFilter := 'XSL files (*.xsl)';
    sTitle := 'Find the XSL stylesheet file';
  end;
  if Sender = sbtnOutput then
  begin
    sDesc := 'edtOutput';
    sDefaultExt := '';
    sFileName := '*.*';
    sFilter := 'Any file (*.*)';
    sTitle := 'Select the output file';
  end;
  if Sender = sbtnXslt then
  begin
    sDesc := 'edtXslt';
    sDefaultExt := 'saxon.exe';
    sFileName := 'saxon.exe';
    sFilter := 'SAXON executable (saxon.exe)';
    sTitle := 'Find the SAXON executable';
  end;
  with fodlgOpen do
  begin
    DefaultExt := sDefaultExt;
    FileName := sFileName;
    Filter := sFilter;
    Title := sTitle;
  end;
  if fodlgOpen.Execute then
    TEdit(FindComponent(sDesc)).Text := fodlgOpen.FileName;
end;

procedure TMainFrm.Button1Click(Sender: TObject);
begin
  Close;
end;

procedure TMainFrm.Button2Click(Sender: TObject);
var
  sCommand: String;
begin
// Run Saxon
  sCommand:=Trim(edtXslt.Text)+' -o '+Trim(edtOutput.Text)+
' '+Trim(edtXml.Text)+' '+Trim(edtXsl.Text);
  WinExec(PChar(sCommand),SW_SHOW);
end;

procedure TMainFrm.FormActivate(Sender: TObject);
var
  fIni: TInifile;
begin
  try
    fIni := TInifile.Create(ExtractFilePath(Application.ExeName)+
'/PDSrunxslt.ini');
    edtXml.Text := fIni.ReadString('PATHS','XMLfile','*.xml');
    edtXsl.Text := fIni.ReadString('PATHS','XSLfile','*.xsl');
    edtOutput.Text := fIni.ReadString('PATHS','Outfile','*.*');
    edtXslt.Text := fIni.ReadString('PATHS','Saxon','saxon.exe');
  finally
    fIni.Destroy;
  end;
end;

end.

Java

Zdrojový kód:
import javax.swing.UIManager;
import java.awt.*;
import java.awt.event.*;
import PDSrunxsltw.*;

public class PDSrunxslt {

  public PDSrunxslt() {		// Konstruktor aplikace
    PDSrunxsltw o = new PDSrunxsltw();
    Dimension obr = Toolkit.getDefaultToolkit().getScreenSize();
    Dimension ro = new Dimension();
    o.setTitle("XML+XSL -> output");
    o.setVisible(true);
    o.addWindowListener(new WindowAdapter() {
	public void windowClosing(WindowEvent e)
	{ System.exit(0); }
    });
  }
	
  public static void main(String[] args) {
    try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
    catch(Exception e) {
      e.printStackTrace();
    }
    new PDSrunxslt();
  }
}

public class PDSrunxsltw extends JFrame
{
  public PDSrunxsltw()	
  {
    Dimension obr = Toolkit.getDefaultToolkit().getScreenSize();
    Dimension ro = new Dimension();
    ro.height = 150;
    ro.width = 400;
    setSize(ro);
    setResizable(false);
    setLocation(ro.width/2,ro.height/2);
    setTitle("Titulek");

    JLabel lblXml = new JLabel("XML file:");
    JLabel lblXsl = new JLabel("XSL file:");
    JLabel lblOut = new JLabel("Output file:");
    JLabel lblXslt = new JLabel("Saxon:");

    
    final JTextField edtXml = new JTextField("*.xml");
    final JTextField edtXsl = new JTextField("*.xsl");
    final JTextField edtOut = new JTextField("*.htm");
    final JTextField edtXslt = new JTextField("saxon.exe");
    nactiKlice(edtXml,edtXsl,edtOut,edtXslt);

    JButton btnXml = new JButton("...");
    btnXml.setToolTipText("Search the XML source file");
    btnXml.addActionListener(new ActionListener() 
    {
      public void actionPerformed(ActionEvent e) 
      {
edtXml.setText(nactiSoubor("Search the XML source file","*.xml"));
      }
     });
    

    JButton btnXsl = new JButton("...");
    btnXsl.setToolTipText("Search the XSL stylesheet file");
    btnXsl.addActionListener(new ActionListener() 
    {
      public void actionPerformed(ActionEvent e) 
      {
edtXsl.setText(nactiSoubor("Search the XSL stylesheet file","*.xsl"));
      }
     });

    JButton btnOut = new JButton("...");
    btnOut.setToolTipText("Search the output file");
    btnOut.addActionListener(new ActionListener() 
    {
      public void actionPerformed(ActionEvent e) 
      {
        edtOut.setText(nactiSoubor("Search the output file","*.*"));
      }
     });

    JButton btnXslt = new JButton("...");
    btnXslt.setToolTipText("Search the XSLT processor");
    btnXslt.addActionListener(new ActionListener() 
    {
      public void actionPerformed(ActionEvent e) 
      {
edtXslt.setText(nactiSoubor("Search the XSLT processor","*saxon.exe"));
      }
     });

    JButton btnQuit = new JButton("Quit");
    btnQuit.setToolTipText("Quit the application");
    btnQuit.addActionListener(new ActionListener() 
    {
      public void actionPerformed(ActionEvent e) 
      {
        System.exit(0); 
      }
     });

    JButton btnExec = new JButton("XSLT transformation");
    btnExec.setDefaultCapable(true);  
    btnExec.setToolTipText("Perform the XSLT transformation");
    btnExec.addActionListener(new ActionListener() 
    {
      public void actionPerformed(ActionEvent e) 
      {
        String sCommand;
sCommand=edtXslt.getText()+" -o "+edtOut.getText()+" "+
edtXml.getText()+ " " + edtXsl.getText();
        try        
        { 
          Process p = Runtime.getRuntime().exec(sCommand);
        }
        catch(IOException io)
	{ 
System.out.println("IO Exception caught: " + io.getMessage());
	}
JOptionPane.showMessageDialog(new JFrame(),"Transformation done.");
      }
     });
    
    JPanel contentPane = new JPanel();
    contentPane.setLayout(new GridBagLayout());
    GridBagConstraints lXml = new GridBagConstraints();
    lXml.gridy = 0; 
    lXml.gridx = 0;
    lXml.fill = GridBagConstraints.BOTH;
    contentPane.add(lblXml, lXml);

    GridBagConstraints eXml = new GridBagConstraints();
    eXml.gridy = 0; 
    eXml.gridx = 1;
    eXml.fill = GridBagConstraints.BOTH;
    eXml.weightx = 1;
    contentPane.add(edtXml, eXml);

    GridBagConstraints bXml = new GridBagConstraints();
    bXml.gridy = 0; 
    bXml.gridx = 2;
    contentPane.add(btnXml, bXml);

    GridBagConstraints lXsl = new GridBagConstraints();
    lXsl.gridy = 1; 
    lXsl.gridx = 0;
    lXsl.fill = GridBagConstraints.BOTH;
    contentPane.add(lblXsl, lXsl);

    GridBagConstraints eXsl = new GridBagConstraints();
    eXsl.gridy = 1; 
    eXsl.gridx = 1;
    eXsl.fill = GridBagConstraints.BOTH;
    contentPane.add(edtXsl, eXsl);

    GridBagConstraints bXsl = new GridBagConstraints();
    bXsl.gridy = 1; 
    bXsl.gridx = 2;
    contentPane.add(btnXsl, bXsl);

    GridBagConstraints lOut = new GridBagConstraints();
    lOut.gridy = 2; 
    lOut.gridx = 0;
    lOut.fill = GridBagConstraints.BOTH;
    contentPane.add(lblOut, lOut);

    GridBagConstraints eOut = new GridBagConstraints();
    eOut.gridy = 2; 
    eOut.gridx = 1;
    eOut.fill = GridBagConstraints.BOTH;
    contentPane.add(edtOut, eOut);

    GridBagConstraints bOut = new GridBagConstraints();
    bOut.gridy = 2; 
    bOut.gridx = 2;
    contentPane.add(btnOut, bOut);

    GridBagConstraints lXslt = new GridBagConstraints();
    lXslt.gridy = 3; 
    lXslt.gridx = 0;
    lXslt.fill = GridBagConstraints.BOTH;
    contentPane.add(lblXslt, lXslt);

    GridBagConstraints eXslt = new GridBagConstraints();
    eXslt.gridy = 3; 
    eXslt.gridx = 1;
    eXslt.fill = GridBagConstraints.BOTH;
    contentPane.add(edtXslt, eXslt);

    GridBagConstraints bXslt = new GridBagConstraints();
    bXslt.gridy = 3; 
    bXslt.gridx = 2;
    contentPane.add(btnXslt, bXslt);
    
    GridBagConstraints bQuit = new GridBagConstraints();
    bQuit.gridy = 4; 
    bQuit.gridx = 0;
    bQuit.fill = GridBagConstraints.BOTH;
    contentPane.add(btnQuit, bQuit);

    GridBagConstraints bExec = new GridBagConstraints();
    bExec.gridy = 4; 
    bExec.gridx = 1;
    bExec.gridwidth = 2;
    bExec.fill = GridBagConstraints.BOTH;
    contentPane.add(btnExec, bExec);

    setContentPane(contentPane);
  	
    addWindowListener(new WindowAdapter() 
    {
      public void windowClosing(WindowEvent e)
      { 
        System.exit(0); 
      }
    });
  } 

  protected String nactiSoubor(String sTitle, String sFile)
  {
    File soubor = new File(sFile);
    JFileChooser vyberSoubor = new JFileChooser();
    vyberSoubor.setCurrentDirectory(soubor);
    vyberSoubor.setDialogTitle(sTitle);
    int vysledek = vyberSoubor.showOpenDialog(this);
    if(vysledek == JFileChooser.APPROVE_OPTION)
    {
return vyberSoubor.getSelectedFile().getPath() + 
vyberSoubor.getSelectedFile().separator + 
vyberSoubor.getSelectedFile().getName(); 
    }
    else
    {
      return "";
    }
  };

protected void nactiKlice(JTextField eXml, JTextField eXsl, 
JTextField eOut, JTextField eSax)
  {
    File fIni = new File("PDSrunxslt.ini");
    if (fIni.exists()) 
    {
      try
      { 
        FileInputStream fisIni = new FileInputStream(fIni);
        DataInputStream disIni = new DataInputStream(fisIni);
        String sLine;

        while ((sLine = disIni.readLine()) != null)
        { 
          if (sLine.indexOf("XMLFILE") > -1)
          { 
             eXml.setText(sLine.substring(8));
          };  
          if (sLine.indexOf("XSLFILE") > -1) 
          { 
             eXsl.setText(sLine.substring(8));
          };  
          if (sLine.indexOf("OUTFILE") > -1) 
          { 
             eOut.setText(sLine.substring(8));
          };  
          if (sLine.indexOf("SAXON") > -1) 
          { 
             eSax.setText(sLine.substring(6));
          };  
        };
        disIni.close();
        fisIni.close();
      }
      catch(IOException io)
      {
	System.out.println("IO Exception caught: " + io.getMessage());
      }
    };
  };

}

Python

Zdrojový kód:
from Tkinter import * 
from tkFileDialog import *
import tkMessageBox
import os
import re
import string

def NactiIni():
   try:
       myFile = open("PDSrunxslt.ini", "r",0)
       try:

           while 1: 
               line = myFile.readline()
               if not line:
                   break
               if re.match("XMLFILE=*",line):
xmlfile.set(string.strip(re.sub("XMLFILE=","",line)))
               if re.match("XSLFILE=*",line):
xslfile.set(string.strip(re.sub("XSLFILE=","",line)))
               if re.match("OUTFILE=*",line):
outfile.set(string.strip(re.sub("OUTFILE=","",line)))
               if re.match("SAXON=*",line):
xsltprocessor.set(string.strip(re.sub("SAXON=","",line)))
       finally:
           myFile.close()
   except IOError:
       pass

def ProchazetXml():
   myFile = askopenfilename(filetypes=[("Xml files", "*.xml")])
   xmlfile.set(myFile)

def ProchazetXsl():
   myFile = askopenfilename(filetypes=[("Xsl files", "*.xsl")])
   xslfile.set(myFile)

def ProchazetOut():
   myFile = askopenfilename(filetypes=[("all files", "*.*")])
   outfile.set(myFile)

def ProchazetSax():
myFile=askopenfilename(filetypes=[("SAXON executable", "saxon.exe")])
   xsltprocessor.set(myFile)

def Konverze():
sCommand = xsltprocessor.get()+ " -o " + outfile.get() + " " +
 xmlfile.get() + " " + xslfile.get()
   os.system(sCommand)
   tkMessageBox.showinfo("Info","XSLT transformation done")


class Application(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.grid()
        self.createWidgets()
    def createWidgets(self):
        global xmlfile
        global xslfile
        global outfile
        global xsltprocessor

        xmlfile = StringVar()
        xslfile = StringVar()
        outfile = StringVar()
        xsltprocessor = StringVar()

        xmlfile.set("*.xml")   
        xslfile.set("*.xsl")   
        outfile.set("*.*")   
        xsltprocessor.set("saxon.exe")   

        NactiIni()

        self.xml = Label(self,text="XML file:") 
        self.xsl = Label(self,text="XSL file:") 
        self.out = Label(self,text="Output file:") 
        self.xslt = Label(self,text="XSLT processor:") 
        self.b1 = Button (self,text="Quit",command=self.quit)
          
        self.xmlf = Entry(self,width=50,textvariable=xmlfile)
        self.xslf = Entry(self,width=50,textvariable=xslfile)
        self.outf = Entry(self,width=50,textvariable=outfile)
        self.xsltf = Entry(self,width=50,textvariable=xsltprocessor)
self.b2 = Button (self,text="XSLT transformation",command=Konverze)

        self.b3 = Button (self,text="...",command=ProchazetXml)
        self.b4 = Button (self,text="...",command=ProchazetXsl)
        self.b5 = Button (self,text="...",command=ProchazetOut)
        self.b6 = Button (self,text="...",command=ProchazetSax)

        self.xml.grid(row=0,column=0,sticky="news")
        self.xsl.grid(row=1,column=0,sticky="news")
        self.out.grid(row=2,column=0,sticky="news")
        self.xslt.grid(row=3,column=0,sticky="news")

        self.xmlf.grid(row=0,column=1,sticky="news")
        self.xslf.grid(row=1,column=1,sticky="news")
        self.outf.grid(row=2,column=1,sticky="news")
        self.xsltf.grid(row=3,column=1,sticky="news")

        self.b1.grid(row=4,column=0,sticky="news")
        self.b2.grid(row=4,column=1,columnspan=2,sticky="news")
        self.b3.grid(row=0,column=2,sticky="news")
        self.b4.grid(row=1,column=2,sticky="news")
        self.b5.grid(row=2,column=2,sticky="news")
        self.b6.grid(row=3,column=2,sticky="news")


app = Application() # Instantiate the application class
app.master.title("XML+XSL -> output")
app.mainloop()

Tcl

Zdrojový kód:
wm title . "XML+XSL -> output"

# Definice globalnich promennych s preddefinovanymi nazvy souboru
set xmlfile           "*.xml"
set xslfile           "*.xsl"
set outfile           "*.*"
set xsltprocesor      "saxon.exe"


# Nacteni vychozich hodnot z INI souboru
set fileId [open "PDSrunxslt.ini" r]
while {[gets $fileId line] >= 0} {

if [regexp {SAXON=*} $line match] {regsub {SAXON=} $line {} xsltprocessor}
if [regexp {XMLFILE=*} $line match] {regsub {XMLFILE=} $line {} xmlfile}
if [regexp {XSLFILE=*} $line match] {regsub {XSLFILE=} $line {} xslfile}
if [regexp {OUTFILE=*} $line match] {regsub {OUTFILE=} $line {} outfile}
}
close $fileId

# Procedura spoustejici transformaci XML souboru
proc Konverze {} {

global xmlfile
global xslfile
global outfile
global xsltprocesor

# Volani XSLT procesoru - saxon
    exec $xsltprocesor -o $outfile $xmlfile $xslfile

# Msgbox s vysledkem 
    set result [tk_messageBox \
    -type ok \
    -message "XSLT transformation done" \
    -icon info \
    -parent . \
    -title "Confirmation ..."]
}

# Procedura pro vyhledavani souboru XML
proc ProchazetXml {} {

global xmlfile
set types {
    {{XML Files}       {.xml}        }
    {{All Files}        *            }
}
set xmlfile [tk_getOpenFile -filetypes $types \
                            -defaultextension .xml ]
}

# Procedura pro vyhledavani souboru XSL
proc ProchazetXsl {} {

global xslfile
set types {
    {{XSL Files}       {.xsl}        }
    {{All Files}        *            }
}
set xslfile [tk_getOpenFile -filetypes $types \
                            -defaultextension .xsl ]
}

# Procedura pro vyhledavani souboru
proc ProchazetOut {} {

global outfile
set types {
    {{All Files}        *            }
}
set outfile [tk_getOpenFile -filetypes $types]
}

# Procedura pro vyhledavani souboru SAXON
proc ProchazetSax {} {

global xsltprocesor
set types {
    {{SAXON Executable}       {saxon.exe}        }
    {{All Files}        *            }
}
set xsltprocesor [tk_getOpenFile -filetypes $types]
}


# Definice labelu a tlacitka Quit
label  .xml   -text "XML file:" -justify left
label  .xsl   -text "XSL schema:" -justify left
label  .out   -text "Output file:" -justify left
label  .xslt  -text "XSLT procesor:" -justify left
button .b1    -text "Quit" -command exit

# Definice editu a tlacitka XSLT transformation
entry  .xmlf  -width 50   -textvariable xmlfile
entry  .xslf  -width 50   -textvariable xslfile
entry  .outf  -width 50   -textvariable outfile
entry  .xsltf -width 50   -textvariable xsltprocesor
button .b2    -text "XSLT transformation" -command "Konverze"

# Definice editu a tlacitka XSLT transformation
button  .b3  -text "..." -width 5 -command "ProchazetXml"
button  .b4  -text "..." -command "ProchazetXsl"
button  .b5  -text "..." -command "ProchazetOut"
button  .b6  -text "..." -command "ProchazetSax"
label   .nic -text ""

# Vykresleni obsahu ramcu, ramec f1 zarovnany vlevo, f2 vpravo
grid .xml .xmlf -sticky news
grid .b3 -row 0 -column 2 -sticky news
grid .xsl .xslf .b4 -sticky news
grid .out .outf .b5 -sticky news 
grid .xslt .xsltf .b6 -sticky news
grid .b1 -sticky news
grid .b2 -row 4 -column 1 -columnspan 2 -sticky news
grid columnconfigure . {1} -weight 1

Perl

Zdrojový kód:
use Tk;

my $main = MainWindow->new;
$main->title('XML+XSL -> output');
$main -> resizable ('0','0');

$xmlfile = "*.xml";
$xslfile = "*.xsl";
$outfile = "*.*";
$xsltprocesor = "saxon.exe";

&NactiIni;

$lblXml = $main->Label(-text => 'XML file:')->grid(-row => 0,
-column => 0,-sticky => news);
$lblXsl = $main->Label(-text => 'XSL file:')->grid(-row => 1,
-column => 0,-sticky => news);
$lblOut = $main->Label(-text => 'OUT file:')->grid(-row => 2,
-column => 0,-sticky => news);
$lblSax = $main->Label(-text => 'XSLT processor:')->grid(
-row => 3,-column => 0,-sticky => news);
$edtXml = $main->Entry(-width => 50,
                       -textvariable => \$xmlfile)->grid(
-row => 0,-column => 1,-sticky => news);
$edtXsl = $main->Entry(-width => 50,
                       -textvariable => \$xslfile)->grid(
-row => 1,-column => 1,-sticky => news);
$edtOut = $main->Entry(-width => 50,
                       -textvariable => \$outfile)->grid(
-row => 2,-column => 1,-sticky => news);
$edtSax = $main->Entry(-width => 50,
                       -textvariable => \$xsltprocesor)->grid(
-row => 3,-column => 1,-sticky => news);
$btnQuit = $main->Button(-text => 'Quit',
                         -command => [$main => 'destroy']
                         )->grid(-row => 4,-column => 0,
-sticky => news);
$btnExec = $main->Button(-text => 'XSLT transformation',
                         -command => [ \&Konverze ]
                         )->grid(-row => 4,-column => 1,
-columnspan => 2,-sticky => news);
$btnXml = $main->Button(-text => '...',
                        -command => [ \&ProchazetXml ]
                        )->grid(-row => 0,-column => 2,
-sticky => news);
$btnXsl = $main->Button(-text => '...',
                        -command => [ \&ProchazetXsl ]
                        )->grid(-row => 1,-column => 2,
-sticky => news);
$btnOut = $main->Button(-text => '...',
                        -command => [ \&ProchazetOut ]
                        )->grid(-row => 2,-column => 2,
-sticky => news);
$btnSax = $main->Button(-text => '...',
                        -command => [ \&ProchazetSax ]
                        )->grid(-row => 3,-column => 2,
-sticky => news);
MainLoop;

sub ProchazetXml {
    $FSref = $main->FileSelect(-filter => "*.xml",
                               -verify => ['-T']);
    $xmlfile = $FSref->Show;
}

sub ProchazetXsl {
    $FSref = $main->FileSelect(-filter => "*.xsl",
                               -verify => ['-T']);
    $xslfile = $FSref->Show;
}

sub ProchazetOut {
    $FSref = $main->FileSelect(-filter => "*.*",
                               -verify => ['-T']);
    $outfile = $FSref->Show;
}

sub ProchazetSax {
    $FSref = $main->FileSelect(-filter => "saxon.exe");
    $xsltprocesor = $FSref->Show;
}

sub Konverze {
   $com = $xsltprocesor . " -o " . $outfile . " " . 
$xmlfile . " " . $xslfile;
   system $com;
   $r = $main->messageBox(-message => "Transformation done.");
}

sub NactiIni {
    open(INIfile,"PDSrunxslt.ini") or die;
    while ($line = ) {
        chomp($line);
        if ($line=~/XMLFILE=/) {
            $line=~s/XMLFILE=//;
            $xmlfile=$line;
        }
        if ($line=~/XSLFILE=/) {
            $line=~s/XSLFILE=//;
            $xslfile=$line;
        }
        if ($line=~/OUTFILE=/) {
            $line=~s/OUTFILE=//;
            $outfile=$line;
        }
        if ($line=~/SAXON=/) {
            $line=~s/SAXON=//;
            $xsltprocesor=$line;
        }
    }
    close(INIfile);
}

Ruby

Zdrojový kód:
require "tk"

class PDSrunxslt

  def prochazetXml
     @xmlfile.value = Tk.getOpenFile("parent"=>Tk.root,
     "defaultextension"=>"*.xml","title"=>"Search the XML source file",
     "filetypes"=>[["XML Files", [".xml"]]])
  end

  def prochazetXsl 
     @xslfile.value = Tk.getOpenFile("parent"=>Tk.root,
     "defaultextension"=>"*.xsl","title"=>"Search the XSL styleshhet",
     "filetypes"=>[["XSL Files", [".xsl"]]])
  end

  def prochazetOut 
     @outfile.value = Tk.getOpenFile("parent"=>Tk.root,
     "defaultextension"=>"*.*","title"=>"Search the output file")
  end

  def prochazetSax 
     @xsltprocessor.value = Tk.getOpenFile("parent"=>Tk.root,
     "defaultextension"=>"saxon.exe","title"=>
     "Search the SAXON executable","filetypes"=>
     [["SAXON executable", ["saxon.exe"]]])
  end

  def konverze 
    @arg = TkVariable.new(value=" -o " + @outfile.value + " " 
    + @xmlfile.value + " " + @xslfile.value);
    system(@xsltprocessor.value,@arg.value)
    Tk.messageBox("message" => "Transformation done.");
  end

  def nactiIni
    iniFile = File.new("PDSrunxslt.ini")
    begin
      iniFile.each_line { |line|
           if line =~ /XMLFILE=/
             line.sub!(/XMLFILE=/,"")  
             @xmlfile.value = line.strip
           end 
           if line =~ /XSLFILE=/
             line.sub!(/XSLFILE=/,"")  
             @xslfile.value = line.strip
           end 
           if line =~ /OUTFILE=/
             line.sub!(/OUTFILE=/,"")  
             @outfile.value = line.strip
           end 
           if line =~ /SAXON=/
             line.sub!(/SAXON=/,"")  
             @xsltprocessor.value = line.strip
           end 
        }
    ensure
        iniFile.close
    end
  end

  def initialize

    root = TkRoot.new{title "XML+XSL -> output"}
    root.resizable("0","0")
    top = TkFrame.new(root)
    c1 = proc { prochazetXml }
    c2 = proc { prochazetXsl }
    c3 = proc { prochazetOut }
    c4 = proc { prochazetSax }
    c5 = proc { konverze }
    
    @xmlfile = TkVariable.new(value="*.xml")
    @xslfile = TkVariable.new(value="*.xsl")
    @outfile = TkVariable.new(value="*.*")
    @xsltprocessor = TkVariable.new(value="saxon.exe")

    nactiIni

    @lblXml = TkLabel.new(top) {text "XML file:";
    grid("row" => 0,"column" => 0,"sticky" => "news")}
    @lblXsl = TkLabel.new(top) {text "XSL file:"; 
    grid("row" => 1,"column" => 0,"sticky" => "news")}
    @lblOut = TkLabel.new(top) {text "OUTPUT file:" ; 
    grid("row" => 2,"column" => 0,"sticky" => "news")}
    @lblSax = TkLabel.new(top) {text "XSLT processor:" ; 
    grid("row" => 3,"column" => 0,"sticky" => "news")}

    @edtXml = TkEntry.new(top,"textvariable" => @xmlfile,
    "width" => 50).grid("row" => 0,"column" => 1,"sticky" => "news")
    @edtXsl = TkEntry.new(top,"textvariable" => @xslfile,
    "width" => 50).grid("row" => 1,"column" => 1,"sticky" => "news")
    @edtOut = TkEntry.new(top,"textvariable" => @outfile,
    "width" => 50).grid("row" => 2,"column" => 1,"sticky" => "news")
    @edtSax = TkEntry.new(top,"textvariable" => @xsltprocessor,
    "width" => 50).grid("row" => 3,"column" => 1,"sticky" => "news")

    @btnQuit = TkButton.new(top) {text "Quit"; command {proc exit}; 
    grid("row" => 4,"column" => 0,"sticky" => "news")}
    @btnExec = TkButton.new(top) {text "XSLT transformation"; 
    command c5; grid("row" => 4,"column" => 1,"columnspan" => 2,
    "sticky" => "news")}
    @btnXml = TkButton.new(top) {text "..."; command c1; 
    grid("row" => 0,"column" => 2,"sticky" => "news")}
    @btnXsl = TkButton.new(top) {text "..."; command c2; 
    grid("row" => 1,"column" => 2,"sticky" => "news")}
    @btnOut = TkButton.new(top) {text "..."; command c3; 
    grid("row" => 2,"column" => 2,"sticky" => "news")}
    @btnSax = TkButton.new(top) {text "..."; command c4; 
    grid("row" => 3,"column" => 2,"sticky" => "news")}
    top.grid()
  end
end

PDSrunxslt.new
Tk.mainloop
Delphi 7
Java 1.4.1
Python/Tk 2.2.1
Tcl/Tk 8.4a2
Perl/Tk 5.6.1
Ruby/Tk 1.7.2