欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

使用纯HTML的通用数据管理和服务

程序员文章站 2022-06-28 16:14:35
使用纯html的通用数据管理和服务。然而,为了收集数据,你需要一个数据储存库。要避免使用数据库服务器带来的很多问题,你可以在xml中收集这些数据。下面是我们的项目的基本结构...

使用纯html的通用数据管理和服务。然而,为了收集数据,你需要一个数据储存库。要避免使用数据库服务器带来的很多问题,你可以在xml中收集这些数据。下面是我们的项目的基本结构:

<user>
    <first_name/>
    <last_name/>
    <mi/>
</user>

我最初将数据限制为first name,last name和middle。这个页面之后的基本思想是用户信息在这个页面中获得。在用户信息需求得到满足以后,流程必须被转到下一个逻辑收集步骤。为了使事情变得简单,我将把用户功能包装到一个asp类中。

function coalesce(vvar, valt)
    if vval = "" or vartype(vval) = 1 or vartype(vval) = 0 then
        coalesce = valt
    else
        coalesce = vval
    end if
end function

class cuser
private m_sql, m_dom

public property get dom()
    set dom = m_dom
end property

public sub saveuser()
    m_sql.save "save_user", m_dom
end sub

public function validate()
    m_dom.loadxml "<root>" & m_sql.validateuser(m_dom) & "</root>"
    if not m_dom.selectsinglenode("//error") is nothing then
        validate = false
    else
        validate = true
    end if
end function

private sub collectdata(dom, ocollection)
    dim nitem, node, parent_node, n, skey
    for nitem = 1 to ocollection.count
        skey = ocollection.key(nitem)
        set parent_node = dom.selectsinglenode("//" & skey & "s")
        if not parent_node is nothing then
            for n = 1 to ocollection(skey).count
                set node = parent_node.selectsinglenode(skey & _
                                                        "[string(.)='" &
ocollection(skey)(n) & "']")
                if node is nothing then
                    set node = dom.createnode(1, skey, "")
                    set node = parent_node.appendchild(node)
                end if
                node.text = coalesce(ocollection(skey)(n), "")
            next
        else
            set node = dom.selectsinglenode("//" & skey)
            if not node is nothing then _
                node.text = coalesce(ocollection(skey), "")
        end if
    next
end sub

private sub class_initialize()
    set m_sql = new csql
    set m_dom = server.createobject("msxml2.domdocument")
    m_dom.async = false
    if vartype(request ("txtuserxml")) = 0 or request ("txtuserxml") = "" then
        m_dom.loadxml request("txtuserxml")
    else
        m_dom.load "<root>" & server.mappath("user.xml") & "</root>"
    end if
    collectdata m_dom, request.form
    collectdata m_dom, request.querystring
end sub

private sub class_terminate()
    set m_sql = nothing
    set m_dom = nothing
end sub

end class

class csql
private m_dal, m_stream

public function save(sstoredproc, odom)
    'advarchar = 200
    m_dal.runsp array(m_dal.mp("@xml_param", 200, 8000, odom.xml))
end function

public function validateuser(odom)
    set m_stream = m_dal.runspreturnstream("validate_user", array(_
            m_dal.mp("@xml_param", 200, 8000, odom.xml)))
    validateuser = m_stream.readtext(-1)
    m_stream.close
end function

private sub class_initialize()
    set m_dal = server.createobject("mypkg.mydal")
    m_dal.getconnection "some connection string"
    set m_stream = server.createobject("adodb.stream")
end sub

private sub class_terminate()
    set m_dal = nothing
    set m_stream = nothing
end sub

end class
csql类是基于一个数据访问层(m_dal)组件mypkg.mydal建立起来的。而这个组件则是基于fitch和mather dal组件建立起来的,这两个组件可以从msdn找到。这样我们就在sql server与你的代码建立了桥梁。

 
当cuser对象初始化之后,它收集request数据并使用collectdata()子函数将收集到的数据放到userdom的一个相应的节点中。(代码我不再解释,因为它本身相当容易理解。)在收集了数据之后(或者不收集数据),我们将使用xsl将数据内容转变成布局。

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl=http://www.w3.org/1999/xsl/transform
    version="1.0">
<xsl:output method="html"/>

<xsl:template match="/">
    <xsl:if test="//error">
    <font color="red">*information in red is required<br/></font>
    </xsl:if>
    <xsl:apply-templates select="//user"/>
</xsl:template>

<xsl:template match="user">
    <font>
        <xsl:attribute name="color">
            <xsl:choose>
                <xsl:when test="//error[.='first name']">red</xsl:when>
                <xsl:otherwise>black</xsl:otherwise>
            </xsl:choose>
        </xsl:attribute>
    first name:
    </font>
    <input type="text" name="first_name">
        <xsl:attribute name="value"><xsl:value-of
select="first_name"/></xsl:attribute>
    </input><br/>
    <font>
        <xsl:attribute name="color">
            <xsl:choose>
                <xsl:when test="//error[.='mi']">red</xsl:when>
                <xsl:otherwise>black</xsl:otherwise>
            </xsl:choose>
        </xsl:attribute>
    mi:
    </font>
    <input type="text" name="mi">
        <xsl:attribute name="value"><xsl:value-of select="mi"/></xsl:attribute>
    </input><br/>
    <font>
        <xsl:attribute name="color">
            <xsl:choose>
                <xsl:when test="//error[.='last_name']">red</xsl:when>
                <xsl:otherwise>black</xsl:otherwise>
            </xsl:choose>
        </xsl:attribute>
    last name:
    </font>
    <input type="text" name="last_name">
        <xsl:attribute name="value"><xsl:value-of
 select="last_name"/></xsl:attribute>
    </input><br/>
</xsl:template>

</xsl:stylesheet>

这个样式表将把内容转成布局。错误检查是很重要的,存储过程通过确定数据是否需要处理来检查数据。对于不能为空但又没有填充数据的每个域返回一个“errors”节点。这个xml的输出大致如下:

    <user>. . .</user><errors><error>first_name</error>. . .</errors>
这个样式表将把内容转成布局。错误检查是很重要的,存储过程通过确定数据是否需要处理来检查数据。对于不能为空但又没有填充数据的每个域返回一个“errors”节点。这个xml的输出大致如下:

    <user>. . .</user><errors><error>first_name</error>. . .</errors>

注意如果有一个错误匹配了节点名,那么产生的输出将会是红色的。我们需要下面的一个asp将前面的所有东西组合起来。

<%@ language=vbscript %>
<%
option explicit
dim ouser
set ouser = new cuser
if ouser.validate() then
    set ouser = nothing
    server.transfer "nextpage.asp"
end if
%>
<html>
<body>
<form method="post" action="getuser.asp" name="thisform" id="thisform">
<%
response.write xsltransform(ouser.dom, "user.xsl")
%>
<input type="hidden" name="txtuserxml" id="txtuserxml"
 value="<%=ouser.dom.xml%>">
<input type="submit" value="submit">
</form>
</body>
</html>
<%
set ouser = nothing

function xsltransform(vxml, xslfilename)
    dim m_xml, m_xsl
    if vartype(vxml) = 8 then
        set m_xml = m_dom
        m_xml.loadxml vxml
    elseif vartype(vxml) = 9 then
        set m_xml = vxml
    end if
    if m_xml.parseerror.errorcode <> 0 then _
        err.raise vbobjecterror, "xmltransform(...)", m_xml.parseerror.reason
    set m_xsl = server.createobject("msxml2.domdocument")
    m_xsl.async = false
    m_xsl.load server.mappath(xslfilename)
    if m_xsl.parseerror.errorcode <> 0 then _
        err.raise vbobjecterror, "xmltransform(...)", m_xsl.parseerror.reason
    xsltransform = m_xml.transformnode(m_xsl)
    set m_xsl = nothing
end function
%>
<!--#include file="cuser.asp"-->

asp代码创建cuser对象,如果有数据就填充数据。然后使用cuser的dom通过xsl转换来创建结果html。转换被包装到一个叫做xsltransform的函数之中。而且,记住要将结果cuser dom存储到一个隐藏的<input>元素中。或者你可以将cuser dom存储到一个session变量中并在初始化过程中将其取出。

在完成这个页面之后,你可以基于前面的骨架代码创建其它的页面。现在你已经创建了一个数据收集的拷贝-粘贴方案。这个方案最优美的部分在于所有的输出都是纯html,没有任何浏览器特有的性质或者样式表。而且由于功能都被包装到类中,所以你可以使用xslt产生布局,代码运行相当快。


--------------------------------------------------------------------------------
本文作者:phillip perkins是ajilon consulting的签约人。他的经验很丰富,从机器控制和客户/服务器到企业内部网应用。