昨天学习完第六章后,我一直在想这个问题:我可以使用XSL文件写这个第六章中GridView里的内容吗?如果可以,我可以在DropDownList的不同选项中,更换这个XSL文件吗?
昨天晚上继续翻《精通ASP.NET 2.0+XML+CSS网络开发混合编程》的七、八、九三章,一本书终于全完了,就是,找不到答案
我一直在想,如果布局写在XSL文件中,那网站就完全可以做到随便更换布局的,就是,数据要怎么读取呢?在《用XSL格式化XML文件后输出》里,我有一个xml文件,就可以使用xsl文件格式数据后输出,现在我有的是一个MS SQL数据库,我记得在读《SQL Server 2005 T-SQL数据库设计》的时候,学过select ... for xml的内容,查了一下读书笔记,真的有。。。
select ProductID, Name, ProductNumber from Production.Product as Products where ProductID < 5 for xml auto, ROOT('Store'), elements
使用这一句,在ms sql 2005中,可以通过自带的数据库AdventureWorks输出一个和我需要的xml文件格式全部一样子的内容:
还有就是,SqlCommand有一个ExecuteXmlReader方法。。。
我测试测试,测试出来了,答案出来子,可以这样子做的,布局可以这样子改变,记录测试文件
web.config文件
<connectionStrings>
<add name="db2005" connectionString="Data Source=服务器名;Initial Catalog=AdventureWorks;User ID=数据库用户名;Password=数据库密码" providerName="System.Data.SqlClient" />
</connectionStrings>
横版布局文件:ProductH.xsl
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<table align="center" width="90%" border="2">
<tbody>
<tr bgcolor="#CCFF99">
<th>ProductID</th>
<th>Name</th>
<th>ProductNumber</th>
</tr>
<xsl:apply-templates select="/Store/Products"></xsl:apply-templates>
</tbody>
</table>
</xsl:template>
<xsl:template match="Products">
<tr>
<td>
<xsl:value-of select="ProductID"/>
</td>
<td>
<xsl:value-of select="Name"/>
</td>
<td>
<xsl:value-of select="ProductNumber"/>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
竖横版布局文件:ProductV.xsl
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<table align="center" width="90%" border="2">
<tbody>
<xsl:apply-templates select="/Store/Products"></xsl:apply-templates>
</tbody>
</table>
</xsl:template>
<xsl:template match="Products">
<tr>
<th>ProductID</th>
<td>
<xsl:value-of select="ProductID"/>
</td>
</tr>
<tr>
<th>Name</th>
<td>
<xsl:value-of select="Name"/>
</td>
</tr>
<tr>
<th>ProductNumber</th>
<td>
<xsl:value-of select="ProductNumber"/>
</td>
</tr>
<tr>
<td colspan="2"> </td>
</tr>
</xsl:template>
</xsl:stylesheet>
输出数据的aspx文件:T2005.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="T2005.aspx.cs" Inherits="database_T2005" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>连接sql2005数据库</title>
</head>
<body>
<form id="form1" runat="server">
<div>
布局:
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged"><asp:ListItem Value="H" Text="横版"></asp:ListItem><asp:ListItem Value="V" Text="竖版"></asp:ListItem></asp:DropDownList>
</div>
<asp:Literal ID="Literal1" runat="server"></asp:Literal>
</form>
</body>
</html>
后置代码类:T2005.aspx.cs
using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using System.IO;
public partial class database_T2005 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (ViewState["layout"] == null) { ViewState["layout"] = "ProductH.xsl"; }
ReadDataFromSql2005();
}
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
switch (DropDownList1.SelectedValue)
{
case "H":
ViewState["layout"] = "ProductH.xsl";
break;
case "V":
ViewState["layout"] = "ProductV.xsl";
break;
}
ReadDataFromSql2005();
}
private void ReadDataFromSql2005()
{
//连接数据库
string connectionString = ConfigurationManager.ConnectionStrings["db2005"].ConnectionString;
SqlConnection dbConnect = new SqlConnection(connectionString);
dbConnect.Open();
//读取数据
string commandText = "select ProductID, Name, ProductNumber from Production.Product as Products where ProductID < 5 for xml auto, ROOT('Store'), elements";
SqlCommand dbCommand = new SqlCommand(commandText, dbConnect);
XmlReader xr = dbCommand.ExecuteXmlReader();
//关闭数据库
dbConnect.Close();
ShowDataFormXSL(xr);
}
private void ShowDataFormXSL(XmlReader xr)
{
//创建一个XmlDocument对象,对载入存储信息的XML文件
XmlDocument xDoc = new XmlDocument();
xDoc.Load(xr);
//创建一个XslTransform对象
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(Server.MapPath(ViewState["layout"].ToString()));
//使用XSL文件转换XML文件,结果输出到流
MemoryStream ms = new MemoryStream();
xslt.Transform(xDoc, null, ms);
//设置当前流中的位置是开头,后面可以从开头读起
ms.Seek(0, SeekOrigin.Begin);
//显示结果,从流的当前位置到末尾读取流
StreamReader sr = new StreamReader(ms);
Literal1.Text = sr.ReadToEnd();
}
}
页面运行时有横版和竖版两种布局:
横版
竖版
现在的问题是,如果我使用ms sql 2000,可以吗?以前我没有在ms sql 2000下用过for xml,这个要测试一下
还有就是,有更好的方法吗?如果,一个页面有多个数据块,我怎么把多个数据块全部拼接成一个xml文件呢?一想到这个问题,我就老觉得,这种办法是不可行的。。。
就是,我现在是知道可以通过这个动态样式XSLT改变页面布局的,也可以通过css改变页面的样式,这样子就够了,我知道这个问题是有答案的就够了
下午先测试ms sql 2000下的显示,然后呢,开始看《ASP.NET 2.0 XML高级编程第3版》,这本叫做高级编程的东西,第七章就是《用XSLT转换XML数据》,第十章是《SQL Server 2005的XML集成》,答案可以在这里面找到吗?要不要从头开始翻起呢?高级编程,会有好多我不懂的东西吧?
XSLT有循环语句,这个是以前看动网的时候看到的,测试了一下直接循环写的xsl文件,也可以用
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head>
<title>使用for-each测试</title>
</head>
<body>
<table align="center" width="90%" border="2">
<tr bgcolor="#CCFF99">
<th>ProductID</th>
<th>Name</th>
<th>ProductNumber</th>
</tr>
<xsl:for-each select="/Store/Products">
<tr>
<td>
<xsl:value-of select="ProductID"/>
</td>
<td>
<xsl:value-of select="Name"/>
</td>
<td>
<xsl:value-of select="ProductNumber"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>