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