管理与编程指南


Net.Data 宏的剖析

宏由两部分组成:

在本小节中,用一个 Net.Data 宏说明了宏语言的元素。此示例宏呈示一个表单, 该表单提示要向 REXX 程序传送的信息。宏将此信息传送至名为 ompsamp.cmd 的外部 REXX 程序,该程序回送用户输入的数据。然后在第二个 Web 页面上显示结果。

首先看整个宏,然后详细看每块:

%{ **********************       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>
%}
 

示例宏包含四个主要块:DEFINE、FUNCTION 和两个 HTML 块。在一个 Net.Data 宏中可以有多 个 DEFINE、FUNCTION 和 HTML 块。

两个 HTML 块包含了诸如 HTML 等文本显示语句,这使 Web 宏更容易书写。如果您熟悉 HTML,就知 道构建一个宏只涉及添加要在服务器上动态处理的宏语句和要发送到数据库的 SQL 语句。

虽然宏看起来类似于 HTML 文档,但是 Web 服务器是通过 Net.Data 使用 CGI、 Web 服务器 API 或 Java 小服务程序 来访问它的。要调用宏,Net.Data 需要两个参数:要处理的宏的名称和该宏中要显示的 HTML 块。

调用了宏之后,Net.Data 从头开始处理它。以下各章节着眼于当 Net.Data 处理文件时所发生的事情。

DEFINE 块

DEFINE 块包含了 DEFINE 语言结构以及以后要在 HTML 块中使用的变量定义。下例显 示具有一个变量定义的 DEFINE 块:

%{ **********************       DEFINE Block        ************************%}
%DEFINE{
   page_title="Net.Data Macro Template"
%}

第一行是一个注释。注释是 %{%}中的任何文本。注释可处于宏中的任何地方。下一个语句起始于一 个 DEFINE 块。可以在一个定义块中定义多个变量。在此例中,只定义了一个变量 page_title。定义了该变量之后,就可以使用语法 $(page_title) 在宏中 的任何地方引用它。使用变量便于以后对宏作全局变更。该块的最后一行 %} 标识了 DEFINE 块的结束。

FUNCTION 块

FUNCTION 块包含了对 HTML 块所调用的函数的说明。函数由语言环境处理,可以 执行程序、SQL 查询或存储过程。

以下示例显示了两个 FUNCTION 块。一个定义对外部 REXX 程序的调用, 另一个包含内联的 REXX 语句。

%{ ********************** FUNCTION Block **********************************%}
%FUNCTION(DTW_REXX) rexx1 (IN input) returns(result) { <-- This function accepts
                                                       one parameter and returns the
                                                       variable 'result', which is
                                                       assigned by the external REXX
                                                       program
     %EXEC{ompsamp.cmd %}  <-- The function executes an external REXX program
                               called "ompsamp.cmd"
%}
 
%FUNCTION(DTW_REXX) today () RETURNS(result) {
      result = date()  <-- The single source statement for this function is
                           contained inline.
%}

第一函数块 rexx1 是一个 REXX 函数说明,它依次运行一个 名为 ompsamp.cmd的 外部 REXX 程序。输入变量 input 被该函数接受并自动传送至外部 REXX 命令。REXX 命令 还返回变量 result。REXX 命令中的变量 result 的内容代替 OUTPUT 块中包含的调 用的 @rexx1() 函数调用。REXX 程序可直接访问 inputresult 变量, 正如 ompsamp.cmd源码 中所显示的那样:

/* REXX */
result = 'The REXX program received "'input'" from the macro.'

该函数中的代码回送传送给它的数据。可通过用普通标记样式标记(如 <b> or <em>) 将请求 @rexx1() 函数调用括起来, 以便以您想要的任何方式来格式化结果文本。与 result 变量相比,REXX 程序宁愿使用 REXX SAY 语句来将 HTML 标记写入标准输出。

第二个函数块也引用一个 REXX 程序 today。但是,在此情况下,整个 REXX 程序都包含在本身的函数说明中。不需要外部程序。REXX 和 Perl 函数都允许内联程序,因为它们 是解释语言,可以动态语法分析和执行。内联程序的优点是简明,不需要一个程序文件来管理。第一个 REXX 函数也可以内联处理。

HTML 块

HTML 块定义 Web 页面的布局,引用变量并调用函数。HTML 块被用作宏的入口点 和出口点。HTML 块总是在 Net.Data 宏请求中指定的,并且每个宏必须至少有一个 HTML 块。

示例宏中的第一个 HTML 块名为 INPUTHTML(INPUT) 块包含用于具有 一个输入字段的简单表单的 HTML。

%{ **********************      HTML Block: Input    ************************%}
%HTML (INPUT) {               <--- Identifies the name of this HTML block.
<html>
<head>
<title>$(page_title)</title>  <--- Note the variable substitution.
</head><body>
<h1>Input Form</h1>
Today is @today()             <--- This line contains a call to a function.
 
<form method="post" action="output">  <--- When this form is submitted,
                                           the "OUTPUT" HTML block is called.<p>
Type some data to pass to a REXX program:
<input name="input_data"      <--- "input_data" is defined when the form
TYPE="text" SIZE="30" />           is submitted and can be referenced elsewhere in
                                   this macro. It is initialized to whatever the
                                   user types into the input field.
</p>
<input type="submit" value="enter" />
 
< hr>
<p>
[
<a href="/">Home page</a>]</p>
 </body><html>
%}                            <--- Closes the HTML block.

整个块由 HTML 块标识符 %HTML (INPUT) {...%} 括起来。INPUT 标 识了该块的名称。名称可包含下划线、 句点和字母数字字符;Net.Data 是不分大小写的。HTML <title> 标记包含了变量替换的示例。变量 page_title 的值替换了表单的标题。

此块还具有一个函数调用。表达式 @today() 是对函数 today 的调用 。该函数是在上面描述的 FUNCTION 块中定义的。Net.Data 将 today 函数的结果(即当前日期)插入 HTML 文本中与 @today() 表达式相同的 位置。

FORM 语句的 ACTION 参数提供了一个在 HTML 块之间或在宏之间浏览的示例。表单提交时, ACTION 参数中对另一块名称的引用将访问此块。HTML 表单中的任何输入数据都作为隐式变量传送给块。此表单上定义的单个输入字段,就是这样的。当表单提交时,在此表单中输入的数据被传送到 变量 input_data 中的 HTML(OUTPUT) 块。

如果另一个宏在相同的 Web 服务器上,您就可以用交叉引用来访问该宏中的 HTML 块。例如,ACTION 参数 ACTION="../othermacro.dtw/main" 访问在宏 othermacro.dtw 中称为主程序的 HTML 块。表单中输入的任何数据类型再次在 input_data 中传送给该宏。

在调用 Net.Data 时,您将变量作为 URL 的一部分传送。例如:

<a href="/cgi-bin/db2www/othermacro.dtw/main?input_data=value">Next macro</a>

您可以通过引用表单中指定的变量名来访问或处理宏中的表单数据。

示例中的下一个 HTML 块是 HTML(OUTPUT) 块。它包含 HTML 标记和 Net.Data 宏语句, 这些语句定义 HTML(INPUT) 请求所处理的输出。

%{ **********************    HTML Block: Output     ************************%}
%HTML (OUTPUT) {
<html>
<head>
<title>$(page_title)</title>  <--- More substitution.
 </head><body>
<h1>Output Page</h1>
<p>@rexx1(input_data)  <--- This line contains a call to function rexx1
                            passing the argument "input_data".
<p>
< hr>
<p>
[
<a href="/">Home page</a> |
<a href="input">Previous page</a>]
%}

HTML(INPUT) 块相似,此块也是标准 HTML,其中使用 Net.Data 宏语句来 替换变量和函数调用。再次用 page_title 变量来替换标题语句。与上面相似, 此块也包含一个函数调用。在 此情况下,它调用函数 rexx1 并将变量 input_data 的内容传送给它,该 变量接收自 Input 块中定义的表单。您可以将任何数目的变量传送给函数,或从函数中传送回任 何数目的变量。函数定义指定传递的变量数目及其用法。

XML 块

当您想要将 XML 传递至另一处理应用程序或客户机浏览器时, 可使用 XML 块结构来传递 XML 内容。

XML 块的工作方式与 HTML 块相同;它是宏的入口点。在这个块中,可以直接输入 XML 标记,引用变量和进行函数调用。

因此,您可以定制生成的 XML 文档以满足您的需要,XML 块不生成 prolog 标记。输入您的企业特定的 prolog 信息,并包括您选择的样式表。Net.Data 附带提供了三个您可以使用的 XSL 样式表。这些样式表包含用于 Net.Data 生成的所有 XML 元素的变换。但是这些样式表只是一些示例, 我们鼓励您扩展这些样式表,或创建您自己的样式表。

图 20. 包含 XML 报告块的宏

%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>
%}
 

在调用 SQL 函数以返回缺省报告时,Net.Data 生成使用一小组 XML 元素的结果集, 如以下样本“文档类型描述”(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)>
 

这些元素定义如下:

XMLBlock
文档的根元素。此标记必须人工输入。

RowSet
包含结果集中的行。RowSet 的名称属性按如下方式确定:

Row
包含一行中的列,并作了编号以便于标识。

Column
包含特定行和作为该行命名依据的列的数据值。

ShowSQL
包含用于当前查询的 SQL 语句。

Message
包含 Net.Dta 或 DB2 生成的任何出错信息。

通过使用以上元素,Net.Data 将从图 20中列示的宏生成以下输出。

<?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>
 

图 21图 22显示了 当使用 Net.Data 附带提供的两个样式表(ndTable.xsl 和 ndRecord.xsl)中的每一个时,上述数据在浏览器中的外观。

图 21. 使用 ndTable.xsl 样式表显示的 XML


使用 ndTable.xsl 样式表显示的 XML

图 22. 使用 ndRecord.xsl 样式表显示的 XML


使用 ndTable.xsl 样式表显示的 XML


[ 页的顶部 | 上一页 | 下一页 | 目录 | 索引 ]