Das Makro besteht aus zwei Abschnitten:
Der Deklarationsabschnitt kann darüber hinaus noch weitere Sprachkonstrukte und Anweisungen enthalten, wie z. B. EXEC-Anweisungen, IF-Blöcke, INCLUDE-Anweisungen und MESSAGE-Blöcke. Weitere Informationen zu den Sprachkonstrukten finden Sie im Kapitel über die Sprachkonstrukte im Handbuch Net.Data Reference.
Hinweis zu Berechtigungen: Stellen Sie sicher, dass die Benutzer-ID, unter der Net.Data ausgeführt wird, über eine Berechtigung zum Lesen und Ausführen von Dateien, auf die EXEC-Anweisungen verweisen, und zum Lesen von Dateien, auf die INCLUDE-Anweisungen verweisen, verfügt. Weitere Informationen hierzu finden Sie in Erteilen von Zugriffsrechten für Dateien, auf die Net.Data zugreift.
Im folgenden Abschnitt werden anhand eines einfachen Net.Data-Makros die Elemente der Makrosprache erläutert. Dieses Beispielmakro zeigt ein Formular, das Informationen anfordert, die an ein REXX-Programm übergeben werden. Das Makro übergibt diese Informationen an ein externes REXX-Programm namens ompsamp.cmd, das die vom Benutzer eingegebenen Daten zurückmeldet. Die Ergebnisse werden anschließend auf einer zweiten Webseite angezeigt.
Sehen Sie sich zunächst das gesamte Makro an. Im Folgenden werden dann die einzelnen Blöcke näher erläutert:
%{ ********************** DEFINE block ************************%} %DEFINE { page_title="Net.Data Macro Template" %} %{ ********************** FUNCTION Definition block ************************%} %FUNCTION(DTW_REXX) rexx1 (IN input) returns(result) { %EXEC{ompsamp.cmd %} %} %FUNCTION(DTW_REXX) today () RETURNS(result) { result = date() %} %{ ********************** HTML Block: Input ************************%} %HTML(INPUT){ <html> <head> <title>$(page_title)</title> </head><body> <h1>Input Form</h1> Today is @today() <form method="post" action="output"> Type some data to pass to a REXX program: <input name="input_data" type="text" size="30" /> <p> <input type="submit" value="enter" /> </p> </form> <hr> <p>[<a href="/">Home page</a>] </body></html> %} %{ ********************** HTML Block: Output ************************%} %HTML (OUTPUT) { <html> <head> <title>$(page_title)</title> </head><body> <h1>Output Page</h1> <p>@rexx1(input_data) <p><hr> <p>[<a href="/">Home page</a> | <a href="input">Previous page</a>] </body></html> %}
Das Beispielmakro besteht aus vier Hauptblöcken: dem DEFINE-, dem FUNCTION- sowie den beiden HTML-Blöcken. Ein Net.Data-Makro kann auch mehrere DEFINE-, FUNCTION- und HTML-Blöcke enthalten.
Die beiden HTML-Blöcke enthalten Textdarstellungsanweisungen wie HTML, die das Schreiben von Webmakros sehr einfach machen. Wenn Sie mit HTML vertraut sind, besteht die Erstellung eines Makros nur aus dem Hinzufügen von Makroanweisungen, die dynamisch auf dem Server verarbeitet werden, sowie von SQL-Anweisungen, die an die Datenbank gesendet werden.
Obwohl das Makro einem HTML-Dokument ähnelt, greift der Webserver über Net.Data mit Hilfe von CGI, einer Webserver-API oder einem Java-Servlet darauf zu. Net.Data benötigt zum Aufrufen eines Makros zwei Parameter: den Namen des zu verarbeitenden Makros und den anzuzeigenden HTML-Block in diesem Makro.
Wenn das Makro aufgerufen wird, beginnt Net.Data mit der Verarbeitung am Anfang der Datei. In den folgenden Abschnitten wird die Verarbeitung der einzelnen Blöcke durch Net.Data beschrieben.
Der DEFINE-Block enthält das DEFINE-Sprachkonstrukt und Variablendefinitionen, die später in den HTML-Blöcken verwendet werden. Das folgende Beispiel zeigt einen DEFINE-Block mit einer Variablendefinition:
%{ ********************** DEFINE Block ************************%} %DEFINE { page_title="Net.Data Macro Template" %}
Die erste Zeile ist ein Kommentar. Ein Kommentar ist jeder Text, der in %{ und %} eingeschlossen ist. Kommentare können an jeder beliebigen Stelle im Makro eingefügt werden. Die nächste Anweisung beginnt einen DEFINE-Block. Sie können mehrere Variablen in einem DEFINE-Block definieren. Im vorliegenden Beispiel wird lediglich eine Variable (page_title) definiert. Nach ihrer Definition kann auf diese Variable an jeder Stelle innerhalb des Makros mit der Syntax $(page_title) verwiesen werden. Mit Hilfe der Variablen können Sie zu einem späteren Zeitpunkt auf einfache Art globale Änderungen an Ihrem Makro vornehmen. Die letzte Zeile dieses Blocks, %}, kennzeichnet das Ende des DEFINE-Blocks.
Der FUNCTION-Block enthält die Deklarationen für Funktionen, die von den HTML-Blöcken aufgerufen werden. Funktionen werden von Sprachumgebungen verarbeitet und können Programme, SQL-Abfragen oder gespeicherte Prozeduren ausführen.
Das folgende Beispiel zeigt zwei FUNCTION-Blöcke. Der erste Block definiert den Aufruf eines externen REXX-Programms, und der zweite Block enthält Inline-REXX-Anweisungen.
%{ ********************** FUNCTION Block **********************************%} %FUNCTION(DTW_REXX) rexx1 (IN input) returns(result) { <-- Diese Funktion akzeptiert einen Parameter und gibt die Variable 'result' zurück, die vom externen REXX-Programm zugeordnet wird. %EXEC{ompsamp.cmd %} <-- Die Funktion führt ein externes REXX-Programm namens "ompsamp.cmd" aus. %} %FUNCTION(DTW_REXX) today () RETURNS(result) { result = date() <-- Die einzelne Quellenanweisung für diese Funktion befindet sich inline. %}
Der erste FUNCTION-Block, rexx1, ist die Deklaration einer REXX-Funktion, die ihrerseits ein externes REXX-Programm namens ompsamp.cmd ausführt. Von dieser Funktion wird eine Eingabevariable input entgegengenommen und automatisch an den externen REXX-Befehl übergeben. Der REXX-Befehl gibt außerdem eine Variable namens result zurück. Der Inhalt der Variablen result im REXX-Befehl ersetzt den im OUTPUT-Block enthaltenen Funktionsaufruf @rexx1(). Auf die Variablen input und result kann das REXX-Programm, wie im Quellencode für ompsamp.cmd gezeigt wird, direkt zugreifen:
/* REXX */ result = 'The REXX program received "'input'" from the macro.'
Der Code in dieser Funktion gibt die an sie übergebenen Daten zurück. Sie können den Ergebnistext nach Belieben formatieren, indem Sie den anfordernden Funktionsaufruf @rexx1() zwischen normale HTML-Befehle für Hervorhebungen (wie z. B. <b> oder <em>) setzen. Anstatt die Variable result zu verwenden, hätte das REXX-Programm auch HTML-Befehle mit Hilfe der REXX-Anweisung SAY in die Standardausgabe schreiben können.
Der zweite FUNCTION-Block, today, verweist ebenfalls auf ein REXX-Programm. In diesem Fall befindet sich jedoch das gesamte REXX-Programm selbst innerhalb der Funktionsdeklaration. Ein externes Programm ist nicht erforderlich. Inline-Programme sind für REXX- und Perl-Funktionen zulässig, da REXX und Perl Interpreter-Sprachen sind, die syntaktisch analysiert und dynamisch ausgeführt werden können. Inline-Programme bieten den Vorteil der Einfachheit, da sie keine separat zu verwaltende Programmdatei erfordern. Die erste REXX-Funktion hätte ebenfalls inline angelegt werden können.
HTML-Blöcke definieren das Layout einer Webseite, verweisen auf Variablen und rufen Funktionen auf. HTML-Blöcke werden als Eingangs- und Endpunkte für das Makro verwendet. In der Net.Data-Aufrufanforderung wird immer ein HTML-Block angegeben, und jedes Makro muss mindestens einen HTML-Block enthalten.
Der erste HTML-Block im Beispielmakro heißt INPUT. HTML(INPUT) enthält HTML-Code für ein einfaches Formular mit einem Eingabefeld.
%{ ********************** HTML Block: Input ************************%} %HTML (INPUT) { <--- Gibt den Namen dieses HTML-Blocks an. <html> <head> <title>$(page_title)</title> <--- Beachten Sie die Variablensubstitution. </head><body> <h1>Input Form</h1> Today is @today() <--- Diese Zeile enthält den Aufruf einer Funktion. <form method="post" action="output"> <--- Bei Übergabe dieses Formulars wird der HTML-Block "OUTPUT" aufgerufen.<p> Type some data to pass to a REXX program: <input name="input_data" <--- "input_data" wird bei der Übergabe des Formulars TYPE="text" SIZE="30" /> definiert. Auf diese Variable kann von anderer Stelle des Makros verwiesen werden. Sie wird mit der Benutzereingabe initialisiert. </p> <input type="submit" value="enter" /> <hr> <p> [ <a href="/">Home page</a>]</p> </body><html> %} <--- Beendet den HTML-Block.
Der gesamte HTML-Block wird von der HTML-Blockkennung %HTML (INPUT) {...%} eingeschlossen. INPUT gibt den Namen dieses Blocks an. Der Name kann Unterstreichungszeichen, Punkte und beliebige alphanumerische Zeichen enthalten. Net.Data unterscheidet nicht zwischen Groß- und Kleinschreibung. Der HTML-Befehl <title> enthält ein Beispiel für eine Variablensubstitution. Der Wert der Variablen page_title wird in den Titel des Formulars eingesetzt.
Dieser Block enthält außerdem einen Funktionsaufruf. Der Ausdruck @today() ist ein Aufruf an die Funktion today. Diese Funktion wird im Block FUNCTION definiert, der oben beschrieben ist. Net.Data fügt das Ergebnis der Funktion today, d. h. das aktuelle Datum, in den HTML-Text an der Stelle ein, an der sich der Ausdruck @today() befindet.
Der Parameter ACTION der Anweisung FORM zeigt ein Beispiel für die Navigation zwischen HTML-Blöcken bzw. zwischen Makros. Durch den Verweis auf den Namen eines anderen Blocks in einem Parameter ACTION wird bei der Übergabe des Formulars auf diesen Block zugegriffen. Alle Eingabedaten eines HTML-Formulars werden als implizite Variablen an den neuen Block übergeben. Dies gilt für das einzelne Eingabefeld, das in diesem Formular definiert ist. Bei der Übergabe des Formulars werden die in diesem Formular eingegebenen Daten in der Variablen input_data an den HTML-Block HTML(OUTPUT) übergeben.
Sie können über einen relativen Verweis auf HTML-Blöcke in anderen Makros zugreifen, wenn sich diese Makros auf demselben Webserver befinden. So greift z. B. der ACTION-Parameter ACTION="../othermacro.dtw/main" auf den HTML-Block main im Makro othermacro.dtw zu. Auch hier werden alle in das Formular eingegebenen Daten in der Variablen input_data an dieses Makro übergeben.
Beim Aufrufen von Net.Data wird die Variable als Teil der URL-Adresse weitergegeben. Beispiel:
<a href="/cgi-bin/db2www/othermacro.dtw/main?input_data=value">Next macro</a>
Sie können auf Formulardaten im Makro zugreifen und sie bearbeiten, indem Sie auf den im Formular angegebenen Variablennamen verweisen.
Der nächste HTML-Block des Beispiels ist der Block HTML(OUTPUT). Er enthält HTML-Befehle und Net.Data-Makroanweisungen, die die Verarbeitung der Ausgabe von der Anforderung HTML(INPUT) definieren.
%{ ********************** HTML Block: Output ************************%} %HTML (OUTPUT) { <html> <head> <title>$(page_title)</title> <--- Weitere Substitution </head><body> <h1>Output Page</h1> <p>@rexx1(input_data) <--- Diese Zeile enthält einen Aufruf der Funktion rexx1, die das Argument "input_data" übergibt. <p> <hr> <p> [ <a href="/">Home page</a> | <a href="input">Previous page</a>] %}
Wie der Block HTML(INPUT) besteht auch dieser Block aus Standard-HTML mit Net.Data-Makroanweisungen für die Substitution von Variablen und einem Funktionsaufruf. Auch hier wird in der Titelanweisung der Wert der Variablen page_title eingesetzt. Außerdem enthält dieser Block ebenfalls einen Funktionsaufruf. In diesem Fall wird die Funktion rexx1 aufgerufen, und der Inhalt der Variablen input_data, der von dem im INPUT-Block definierten Formular empfangen wurde, an die Funktion übergeben. Sie können Variablen in beliebiger Zahl an eine Funktion bzw. von einer Funktion übergeben. Die Funktionsdefinition gibt die Anzahl und die Verwendung der übergebenen Variablen an.
Unabhängig davon, ob Sie XML an eine andere Verarbeitungsanwendung oder an einen Client-Browser übergeben wollen, können Sie den XML-Inhalt mit Hilfe der XML-Blockstruktur übergeben.
Der XML-Block funktioniert wie der HTML-Block; es handelt sich um einen Eingangspunkt für das Makro. Innerhalb des Blocks können Sie XML-Befehle direkt eingeben, auf Variablen verweisen und Funktionsaufrufe durchführen.
Damit Sie das generierte XML-Dokument Ihren Erfordernissen entsprechend anpassen können, generiert der XML-Block die Prologbefehle nicht. Geben Sie die Prologinformationen Ihres Unternehmens ein und fügen Sie eine gewünschte Formatvorlage ein. Net.Data verfügt über drei XSL-Formatvorlagen, die Sie verwenden können. Diese Formatvorlagen enthalten Umsetzungen für alle XML-Elemente, die Net.Data generiert. Die Formatvorlagen sind jedoch nur Beispiele, die Sie erweitern oder als Schablone für eigene Formatvorlagen verwenden können.
Abbildung 20. Ein Makro mit einem XML-Berichtsblock
%DEFINE SHOWSQL = "yes" %FUNCTION(DTW_SQL) NewManager(){ select * from staff where job = 'Mgr' and years <= 5 %} %XML(report) { <?xml version="1.0" ?> <?xml-stylesheet type="text/xsl" href="/netdata-xml/ndTable.xsl" ?> <XMLBlock> <h1>List of New Managers</h1> @NewManager() </XMLBlock> %} |
Beim Aufrufen einer SQL-Funktion, die einen Standardbericht ausgibt, generiert Net.Data die Ergebnismenge mit Hilfe einer kleinen Gruppe von XML-Elementen. Siehe hierzu die folgende Beispieldokumentartbeschreibung (Document Type Description, DTD).
<!--------------------------------------------------------> <!-- The root element of the document. --> <!--------------------------------------------------------> <!ELEMENT XMLBlock (RowSet|ShowSQL|Message)*> <!ATTLIST XMLBlock name CDATA #IMPLIED> <!--------------------------------------------------------> <!-- The default presentation format for tables uses --> <!-- the RowSet, Row, and Column elements. --> <!--------------------------------------------------------> <!ELEMENT RowSet (Row)*> <!ATTLIST RowSet name CDATA #IMPLIED> <!ELEMENT Row (Column)*> <!ATTLIST Row name CDATA #IMPLIED number CDATA #IMPLIED> <!ELEMENT Column (#PCDATA)> <!--------------------------------------------------------> <!-- SQL statements resulting from setting the SHOWSQL --> <!-- variable are presented with the ShowSQL element. --> <!--------------------------------------------------------> <!ELEMENT ShowSQL (#PCDATA)> <!--------------------------------------------------------> <!-- Messages are presented with the Message element. --> <!--------------------------------------------------------> <!ELEMENT Message (#PCDATA)>
Die Elemente werden wie folgt definiert:
Bei Verwendung der oben aufgeführten Elemente würde Net.Data die folgende Ausgabe aus dem in Abbildung 20 aufgelisteten Makro generieren.
<?xml version="1.0" ?> <?xml-stylesheet type="text/xsl" href="/netdata-xml/ndTable.xsl" ?> <XMLBlock> <h1>List of New Managers</h1> <ShowSQL>select * from staff where job = 'Mgr' and years <= 5</ShowSQL> <RowSet name="NewManager"> <Row number="1"> <Column name="ID">30</Column> <Column name="NAME">Marenghi</Column> <Column name="DEPT">38</Column> <Column name="JOB">Mgr</Column> <Column name="YEARS">5</Column> <Column name="SALARY">17506.75</Column> <Column name="COMM"></Column> </Row> <Row number="2"> <Column name="ID">240</Column> <Column name="NAME">Daniels</Column> <Column name="DEPT">10</Column> <Column name="JOB">Mgr</Column> <Column name="YEARS">5</Column> <Column name="SALARY">19260.25</Column> <Column name="COMM"></Column> </Row> </RowSet> </XMLBlock>
Abbildung 21 und Abbildung 22 zeigen, wie die Daten oben bei Verwendung der beiden Net.Data-Formatvorlagen (ndTable.xsl und ndRecord.xsl) in einem Browser aussehen würden.
Abbildung 21. XML-Anzeige mit Formatvorlage ndTable.xsl
![]() |
Abbildung 22. XML-Anzeige mit Formatvorlage ndRecord.xsl
![]() |