PPWizard - práce s daty v externích souborech
PPWizard umí nejen vkládat celé externí soubory, či pouze jejich úryvky, ale také umí zpracovat soubory formátu CSV a zvládá i komunikaci s databázemi za využití jazyka SQL. Kromě toho umí z jednoho vstupního souboru generovat více výstupních souborů v různých formátech.
Vložení externího souboru
Zřejmě nejjednodušším a začátečníky nejhledanějším příkazem bude vložení externího souboru. Je jím příkaz #include
. Nejsnadněji ho lze použít pro vložení obsahu celého souboru:
#include "..\soubor.ih"
#include "..<?DirSlash>soubor.ih"
#include "c:\temp\soubor.ih"
#include "\\mojepc\temp\soubor.ih"
V prvním případě, kdy zadáváme pouze název souboru, se tento soubor nejprve hledá v aktuálním adresáři. Jestliže nalezen není, hledá se v adresářích definovaných spouštěcí direktivou /INCLUDEPATH
. Pakliže ani zde PPWizard neuspěje, hledá v adresářích definovaných v systémové proměnné PPWIZARD_INCLUDE
. Poslední prohledávaný adresář je ten, ve kterém je uložen samotný PPWizard.
Na druhém a třetím řádku se soubory hledají v adresářích o úroveň vyšších než v předchozím případě, jinak je pořadí stejné. Třetí řádek je shodný s druhým až na drobný rozdíl, díky kterému se stává nezávislým na platformě. Oním drobným rozdílem je standardní definice <?DirSlash>
, obsahující oddělovač adresářů pro daný operační systém.
Čtvrtý a pátý řádek, myslím si, není třeba vysvětlovat. Soubory jsou tady jednoznačně určeny. Pokud neexistují, preprocesor při zpracovávání těchto příkazů skončí chybou.
Vložení části externího souboru
Příkazem #include
nemusíme vkládat vždy celé soubory, ale také třeba jen jejich části. Třetím parametrem lze definovat řetězec, kterým má být požadovaný fragment souboru vymezen.
#include "soubor.html" "se:|<body>|</body>|"
Na prvním řádku hledá PPWizard v souboru soubor.html posloupnost znaků <!-- obsah -->. Jakmile ji nalezne, začne obsah souboru vkládat, dokud není přerušen opětovným uvedením stejného řetězce.
Na druhém řádku názorně vidíme, jak vymezit začátek a konec vkládaného fragmentu jiným řetězcem. Řetězec začneme se:, pokračujeme oddělovačem, řetězcem pro začátek fragmentu, dalším oddělovačem, řetězcem pro konec fragmentu a posledním oddělovačem. Jako oddělovač je možné použít jakýkoli znak kromě písmena a číslice.
V řetězci nelze bohužel použít regulární výraz. Kdyby to šlo, příkazem #include
by se pěkně přistupovalo k obsahu XML souborů. Mimochodem, funkce pro práci s XML soubory bych vedle regulárních výrazů v PPWizardu opravdu ocenil.
Vložení souboru na úrovni projektu
V našem příkladu webu (viz první článek série) používáme příkaz #include
poněkud zvláštním způsobem. PPWizard totiž nabízí k tomuto jedinému příkazu ekvivalent pro příkazový řádek. V souboru projektu project.ppw máme zápis /#include:macros.ih. Tímto parametrem PPWizardu říkáme, aby při zpracování vložil na úplný začátek každého souboru obsah souboru macros.ih.
Práce s CSV soubory a databázemi
Nejmocnější příkazem pro práci s externími daty je příkaz #import
. S ním můžete přistupovat k souborům typu CSV a k SQL rozhraním databází. V našem ukázkovém webu příkaz #import
v souboru imperdiet.it načítá data ze souboru imperdiet.csv do HTML tabulky. Jak asi tušíte, CSV formát je ideální pro ceníky a podobná tabulková data. Export CSV formátu umožňuje většina tabulkových procesorů.
Výtah ze souboru imperdiet.it:
#(
#import "imperdiet.csv" CMA "" "name" "num1" "num2"
#)
<table>
<tr>
<th>Name</th>
<th>Num1</th>
<th>Num2</th>
</tr>
#{ FOR @@Record = 1 to <?Data:TmpCsv.?>
#if @@Record // 2 = 0
#RexxVar class = "sr"
#else
#RexxVar class = "lr"
#endif
<tr class="<??class>">
<td><?Data:TmpCsv.@@Record.1></td>
<td class="num"><?Data:TmpCsv.@@Record.2></td>
<td class="num"><?Data:TmpCsv.@@Record.3></td>
</tr>
#}
</table>
Pro názornost zredukujme tento celý kód na pouhý jeden řádek:
PPWizardu tím říkáme, že soubor imperdiet.csv obsahuje na každém řádku tři údaje oddělené čárkou. Na výstup tento příkaz vypíše HTML tabulku s hlavičkou popisující první sloupec "name", druhý "num1" a třetí "num2". Nevýhodou je, že se tabulka implicitně naformátuje ne vždy tím nejvhodnějším způsobem. Toto implicitní nastavení můžeme buďto přednastavit nebo můžeme využít cyklů a s výstupem importu pracovat jako s datovým polem.
Právě cyklů využíváme pro přizpůsobení výstupu. Pro pochopení ukázky si však musíme něco říci o datových polích. Ta se definují příkazem #data
. Definujme si třísloupcové pole "mojedata":
"a1" "a2" "a3"
"b1" "b2 "b3"
#data
Pole je uloženo ve standardní definici <?Data:mojedata>
. Pro vypsání prvního řádku a třetího sloupce bychom použili zápis <?Data:mojedata.1.3>. Počet řádků se skrývá pod <?Data:mojedata.?>. Podrobnosti o datových polích najdete v oficiální dokumentaci u popisu funkce #data.
Datová pole už tedy známe a proto zpět k příkladu. Změřme se nyní na tuto konstrukci:
#(
#import "imperdiet.csv" CMA "" "name" "num1" "num2"
#)
Tento, na prvním řádku tochu zvláštní, zápis, převádí soubor imperdiet.csv do datového pole "TmpCvs". To je nyní k dispozici ve standardní definici <?Data:TmpSvc>. (Definice <?Data:TmpSvc.?> pak obsahuje počet řádků a <?Data:TmpSvc.x.y> ypsilontý prvek na ikstém řádku.)
K tomuto datovému poli přistupujeme ve druhé části konstrukce za využítí opakování. Opakování začíná na řádku #{ a končí na #}. S každým cyklem vypíšeme jeden řádek tabulky a zvýšíme hodnotu REXX proměnné "@@Record" o jedna. Tato proměnná nám tak v jednotlivých cyklech odkazuje na záznam, jehož hodnoty vypisujeme. Navíc rozlišujeme lichý řádek od sudého.
Pokročilé možnosti příkazu #import
Základní syntaxe příkazu #import
je následující:
- File2Import - jméno CSV souboru
- ImportType - typ importovaných dat. V příkladu jsme použili CMA, v němž se k oddělování údajů používá čárka. Dalšími možnosti jsou například:
- TAB - údaje oddělené tabulátorem
- SQL - přímý přístup k databázi skrze SQL rozhraní
- ML - údaje jsou odděleny koncem řádku a položky prázdným řádkem
- ??? - použití libovolného oddělovače, v tomto případě znaku "?"
- DefineName - jméno konfigurační řady importu. Implicitní hodnota (pokud není uvedena) je "IMPORT".
- Další parametry jsou názvy položek jednotlivých záznamů. Povinné jsou jen pro některé typy importovaných dat. Vypisují se do hlavičky tabulky, pokud je přímým výstupem příkazu
#import
.
Ve výčtu jsem nakousl konfigurační řady příkazu #import
. Podle typu vstupních dat máme škálu konfiguračních parametrů, kterými si lze přizpůsobit vstup i výstup. Tyto parametry se definují před spuštěním příkazu #import
příkazem #define
. Jejich jméno začíná vždy jménem konfigurační řady (hodnota "DefineName" u příkazu #import
) importu, pokračuje znakem "_" (podtržítko) a končí samotným konfiguračním parametrem. Například takto bychom změnili implicitní nastavení vypisované tabulky:
Jde vlastně o definici makra, jehož jméno je již implicitně v PPWizardu předurčené pro zkrocení výstupu příkazu #import
. O tento typ makra jde i na řádku #define IMPORT_#DATA TmpCsv.
Kdybych měl podrobně probrat příkaz #import
, potřeboval bych na to daleko více místa než jeden článek a přitom bych čtenáře zbytečně zahltil podrobnostmi. Proto jsem se snažil nastínit jen to nejpodstatnější a podat obecný přehled o příkazu. Dále vás již odkáži do oficiální dokumentace na popis funkce #import. Pokud chcete v PPWizardu pracovat s SQL databázemi, pak vás odkáži do oficiální dokumentace na stránky Accessing SQL DATABASES Directly a #import - SQL.
Výstup do jiného souboru
Posledním příkazem, na který se v tomto článku podíváme, je příkaz #output
, se kterým lze přesměrovat výstup do jiného souboru. Příklad:
Soubor test.txt
#output
...
#output "test.txt" Append
Druhý řádek souboru test.txt
#output "test2.txt"
Soubor test2.txt
#output
Třetí řádek souboru test.txt
#output
Na prvním řádku přesměrujeme výstup ze standardního souboru na soubor test.txt. Pokud soubor existuje, bude jeho obsah přepsán. Na třetím řádku, tedy příkazem #output
bez parametru, vrátíme výstup do původního souboru. Na čtvrtém řádku opět přepneme výstup do souboru test.txt. Příkazem Append
zajistíme, aby byl původní soubor zachován a text byl připojen na jeho konec. Výstupem do souboru test2.txt demonstrujeme, že lze příkaz #output
neomezeně vnořovat.