低调大师

您现在的位置是: 首页 > 用XSLT样式表加工后的XML显示DBF文件内容

文章详情

用XSLT样式表加工后的XML显示DBF文件内容

2015-2-3 20:29 30已围观 收藏 加入我们

1.程序需求

在NAS上(可以理解为局域网上一个存放了若干文件的IP地址),有若干个DBF文件,它们占用的空间都不大。现在要做一个功能,就是把这些文件每隔一段时间,做一个快照,以XML形式保存DBF文件的值。并把XML文档保存到指定位置,用已经写好的XSLT样式表,来显示这个XML文件,并提供一些XML文件的统计信息。

2.我的架构

DbfMonitor(程序根目录)
|
|-dbfs(目录)
| |
| |-dbf1(目录)
| | |-dbf1.dbf
| |-dbf2(目录)
| | |-dbf2.dbf
| ...
|
|-xmls(目录)
| |
| |-xml1(目录)
| | |-xml1.xml
| | |-xml1.xslt
| | |-xml1.css(xslt文件调用)
| |-xml2(目录)
| | |-xml2.xml
| | |-xml2.xslt
| | |-xml2.css(xslt文件调用)
| ...
|
|-Dbf2Xml.exe(一个VB.NET程序,将DBF转换到XML)
|-DbfMonitor.bat(单击这个文件运行程序)
|-DbfMonitor.vbs

关于这个程序结构树的说明如下:

1)双击DbfMonitor.bat文件,启动这个程序,DbfMonitor.bat会调用文件DbfMonitor.vbs

2)DbfMonitor.vbs有两个功能:其一为每隔一段时间,将NAS上(或其他任意Windows文件系统可访问到的位置)的DBF文件,同步到本地dbfs目录下;其二为调用程序Dbf2Xml,把DBF文件的内容写到指定的XML文件中,保存到xmls目录下对应的目录中

3)生成XML文件,会引用与之同名的*.xslt文件作为样式表,*.xslt中带有javascript代码,保证每隔一段时间XML文件会刷新一次,用来保证查看到的是最新的DBF文件内容,*.xslt文件还会调用同名的css样式表,用来保证一些界面的美观

3.部分程序代码

1)DbfMonitor.bat

这个文件用来调用DbfMonitor.vbs,代码如下:

@cscript DbfMonitor.vbs
@pause

2)DbfMonitor.vbs

下面的程序,以同步一个A.DBF到A.XML为例:

Option Explicit

WScript.Echo "DBF同步显示工具 2015年2月 Tsybius"
WScript.Echo "--------------------------------"

Dim FSO : Set FSO = WScript.CreateObject("Scripting.FileSystemObject")
Dim WS : Set WS = WScript.CreateObject("WScript.Shell")

'这里设定时间间隔信息
Const Interval = 10000

Dim CurHour 
Dim CurMinute 
Dim CurSecond 

Do

    '打印时间信息
    CurHour = Hour(Now)
    CurMinute = Minute(Now)
    CurSecond = Second(Now)

    WScript.Echo "当前时间: " & CurHour & "时 " & CurMinute & "分 " & CurSecond & "秒"

    'A.DBF
    WScript.Echo "复制文件A.DBF"
    If FSO.FileExists("P:\A.DBF") Then
        FSO.CopyFile "P:\A.DBF", "dbfs\dbf_A\A.dbf", True
        WScript.Echo "A.DBF文件复制完毕: dbfs\dbf_A\A.dbf"
        WS.Run "Dbf2Xml.exe dbfs\dbf_A\A.dbf xmls\xml_A\A.xml A MS_VFP_Oledb", 0
    Else 
        WScript.Echo "未找到A.DBF"
    End If

    WScript.Sleep(Interval)

Loop

3)Dbf2Xml.exe

这是一个用VB.NET语言写的DBF转XML工具

它可以把DBF转换成下面形式的XML文件:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type='text/xsl' href='A.xslt'?>
<DATA COUNT="32" INPUT-DBF="A.dbf" OUTPUT-XML="A.xml">
  <DATA_ROW>
    <列1>列1内容</列1>
    <列2>列2内容</列2>
    列3、列4 ...
  </DATA_ROW>
  <DATA_ROW>
    <列1>列1内容</列1>
    <列2>列2内容</列2>
    列3、列4 ...
  </DATA_ROW>
  行3、行4 ...
</DATA>

这个程序是在一个另一个程序的基础上改写的:http://www.oschina.net/p/curtia_dbf2xml

共有4个参数,分别是DBF文件地址、转换后的XML文件地址、针对该XML转换需要添加的参数(这个参数是在程序中根据实际情况进行改动的)、连接DBF文件使用的连接方式(有多种连接方式时可以配置它)

4)关于xslt文件

对于每一个XML,都要有一个自己专属的XSLT文件与之匹配,这样才能让XML文件显示出想要的东西

下面是一个XML文件示例:A.xml

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type='text/xsl' href='A.xslt'?>
<DATA COUNT="3" INPUT-DBF="A.dbf" OUTPUT-XML="A.xml">
  <DATA_ROW>
    <COLUMN1>A</COLUMN1>
    <COLUMN2>1</COLUMN2>
    <COLUMN3>1</COLUMN3>
    <COLUMN4>1</COLUMN4>
    <COLUMN5>1</COLUMN5>
    <COLUMN6>1</COLUMN6>
    <COLUMN7>1</COLUMN7>
  </DATA_ROW>
  <DATA_ROW>
    <COLUMN1>B</COLUMN1>
    <COLUMN2>3</COLUMN2>
    <COLUMN3>3</COLUMN3>
    <COLUMN4>3</COLUMN4>
    <COLUMN5>3</COLUMN5>
    <COLUMN6>3</COLUMN6>
    <COLUMN7>3</COLUMN7>
  </DATA_ROW>
  <DATA_ROW>
    <COLUMN1>C</COLUMN1>
    <COLUMN2>2</COLUMN2>
    <COLUMN3>2</COLUMN3>
    <COLUMN4>2</COLUMN4>
    <COLUMN5>2</COLUMN5>
    <COLUMN6>2</COLUMN6>
    <COLUMN7>2</COLUMN7>
  </DATA_ROW>
</DATA>

它对应的XSLT文件的示例为:A.xslt

<?xml version="1.0" encoding="gb2312"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="html"/>
  
  <xsl:template match="/">
    <html>
      <head>        
        <meta content="zh-cn" http-equiv="Content-Language"/>
        <meta content="text/html; charset=utf-16" http-equiv="Content-Type"/>
        <link type="text/css" rel="stylesheet" href="A.css"/>
        <title>标题</title>
        
        <script type="text/javascript" language="javascript">
          <xsl:text disable-output-escaping="yes">
          <![CDATA[
          
            function myrefresh()
            {
                window.location.reload();
            }
            setTimeout('myrefresh()', 300000); //在这里指定刷新间隔,单位毫秒
          
          ]]>
        </xsl:text>
        </script>
      </head>
      <body>
        
        <div id="content">
        
          <br />
          数据总计: <strong><font color="red"><xsl:value-of select="DATA/@COUNT" /></font></strong><br />
          输入文件: <strong><font color="red"><xsl:value-of select="DATA/@INPUT-DBF" /></font></strong><br />
          输出文件: <strong><font color="red"><xsl:value-of select="DATA/@OUTPUT-XML" /></font></strong><br />
          
          <hr />
          
          <xsl:variable name="A_1" select="count(DATA/DATA_ROW[COLUMN1='A' and COLUMN2='1'])"/>
          <xsl:variable name="A_2" select="count(DATA/DATA_ROW[COLUMN1='A' and COLUMN2='2'])"/>
          <xsl:variable name="A_3" select="count(DATA/DATA_ROW[COLUMN1='A' and COLUMN2='3'])"/>
          <xsl:variable name="A_4" select="count(DATA/DATA_ROW[COLUMN1='A' and COLUMN2='4'])"/>
          <xsl:variable name="A_5" select="count(DATA/DATA_ROW[COLUMN1='A' and COLUMN2='5'])"/>
          
          <xsl:variable name="B_1" select="count(DATA/DATA_ROW[COLUMN1='B' and COLUMN2='1'])"/>
          <xsl:variable name="B_2" select="count(DATA/DATA_ROW[COLUMN1='B' and COLUMN2='2'])"/>
          <xsl:variable name="B_3" select="count(DATA/DATA_ROW[COLUMN1='B' and COLUMN2='3'])"/>
          <xsl:variable name="B_4" select="count(DATA/DATA_ROW[COLUMN1='B' and COLUMN2='4'])"/>
          <xsl:variable name="B_5" select="count(DATA/DATA_ROW[COLUMN1='B' and COLUMN2='5'])"/>
          
          <xsl:variable name="C_1" select="count(DATA/DATA_ROW[COLUMN1='C' and COLUMN2='1'])"/>
          <xsl:variable name="C_2" select="count(DATA/DATA_ROW[COLUMN1='C' and COLUMN2='2'])"/>
          <xsl:variable name="C_3" select="count(DATA/DATA_ROW[COLUMN1='C' and COLUMN2='3'])"/>
          <xsl:variable name="C_4" select="count(DATA/DATA_ROW[COLUMN1='C' and COLUMN2='4'])"/>
          <xsl:variable name="C_5" select="count(DATA/DATA_ROW[COLUMN1='C' and COLUMN2='5'])"/>
          
          统计信息:<br />
          <table>
          
            <tr>
              <th></th>
              <th>1</th>
              <th>2</th>
              <th>3</th>
              <th>4</th>
              <th>5</th>
            </tr>
            
            <tr>
              <td>A</td>
              <td><xsl:value-of select="$A_1"/></td>
              <td><xsl:value-of select="$A_2"/></td>
              <td><xsl:value-of select="$A_3"/></td>
              <td><xsl:value-of select="$A_4"/></td>
              <td><xsl:value-of select="$A_5"/></td>
            </tr>
            
            <tr>
              <td>B+C</td>
              <td><xsl:value-of select="$B_1+$C_1"/></td>
              <td><xsl:value-of select="$B_2+$C_2"/></td>
              <td><xsl:value-of select="$B_3+$C_3"/></td>
              <td><xsl:value-of select="$B_4+$C_4"/></td>
              <td><xsl:value-of select="$B_5+$C_5"/></td>
            </tr>
            
          </table>
          
          <hr />
          
          <table>
            <tr>
              <th>列1</th>
              <th>列2</th>
              <th>列3</th>
              <th>列4</th>
              <th>列5</th>
              <th>列6</th>
              <th>列7</th>
            </tr>
            <xsl:for-each select="DATA/DATA_ROW">
              <tr>
                <td class="textCentered"><xsl:value-of select="COLUMN1"/></td>
                <td class="textCentered"><xsl:value-of select="COLUMN2"/></td>
                <td class="textCentered"><xsl:value-of select="COLUMN3"/></td>
                <td class="textCentered"><xsl:value-of select="COLUMN4"/></td>
                <td class="textCentered"><xsl:value-of select="COLUMN5"/></td>
                <td class="textCentered"><xsl:value-of select="COLUMN6"/></td>
                <td class="textCentered"><xsl:value-of select="COLUMN7"/></td>
              </tr>
            </xsl:for-each>
          </table>
        </div>
      </body>
    </html>
  </xsl:template>

</xsl:stylesheet>

调用的CSS文件为:A.css

/* Body style, for the entire document */
body
{
    background: #F3F3F4;
    color: #1E1E1F;
    font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
    padding: 0;
    margin: 0;
}
 
/* Header1 style, used for the main title */
h1
{
    padding: 10px 0px 10px 10px;
    font-size: 21pt;
    background-color: #E2E2E2;
    border-bottom: 1px #C1C1C2 solid; 
    color: #201F20;
    margin: 0;
    font-weight: normal;
}
 
/* Table styles */ 
table
{
    border-spacing: 0 0;
    border-collapse: collapse;
    font-size: 10pt;
}
 
table th
{
    background: #3399FF;
    text-align: center;
    text-decoration: none;
    font-weight: normal;
    padding: 3px 6px 3px 6px;
    width:100px;
}
 
table td
{
    vertical-align: top;
    text-align: center;
    padding: 3px 6px 5px 5px;
    margin: 0px;
    border: 1px solid #E7E7E8;
    background: #66FF33;
}
 
.textCentered
{
    text-align: center;
}
 
#content 
{
    padding: 0px 12px 40px 40px; 
}

最终A.xml打开后的效果为:

4.其他注意事项

1)IE浏览器在加载XML时,会提示“为了有利于保护安全性,Internet Explorer已限制此网页运行可以访问计算机的脚本或ActiveX控件。请单击这里获取选项...”,在鼠标右键弹出的菜单中选择“允许阻止的内容”,即可调用javascript代码不断刷新页面

2)Windows的文件系统无法直接通过IP地址获取NAS上的文件,必须要对网络驱动器做完映射后才能通过新赋予的盘符访问NAS上的路径,方法是在桌面上的计算机图标上,单击鼠标右键→映射网络驱动器。如果不进行驱动器映射,在访问时会报错,比如在cmd中使用cd命令访问路径“\\IP地址\目录名\”,会提示“CMD不支持将UNC路径作为当前目录”

3)如果不小心直接点击了*.vbs文件,要关闭它,需要先按下“Ctrl+Alt+Delete”,进入Windows 任务管理器,在进程选项卡中关闭进程wscript.exe

END

文章转载至:https://my.oschina.net/Tsybius2014/blog/375013
收藏 (0)

文章评论

共有0条评论来说两句吧...