如何创建 XML 投票
我们新文章的主题是开发一个简单而漂亮的投票应用程序。
![]() |
![]() |
引言
我们新文章的主题是开发一个简单而漂亮的投票应用程序,我们可以在我们的网站中使用它。虽然大多数示例使用数据库来保存投票数据,但我们的选择将是 XML。
为什么选择 XML?
在实践中,互联网用户对投票等应用程序的兴趣不大。在这种情况下,我们可以假设很多人不能同时投票。在这种情况下,使用 XML 数据结构将是性能和编码的逻辑选择。
投票数据
我们将所有关于投票的数据保存在一个 XML 文件中。作为其结构,虽然提供给用户的值被保存在节点属性中,但收集的投票数据将保存在节点中。
<?xml version="1.0" encoding="iso-8859-9" ?>
<poll name="Which OS do you use?">
<answer text="Windows?">60</answer>
<answer text="Mac OS">15</answer>
<answer text="Linux">8</answer>
<answer text="BeOS">2</answer>
</poll>
注意:将数据文件保存在 App_Data 下将阻止用户直接访问它。
投票 Web 用户控件
为了在网站内提供方便的使用,我们正在将投票应用程序设计为 Web 用户控件。由于该应用程序有两种不同的外观,我们通过利用 MultiView
控件将我们的 ascx 文件分成两个逻辑部分。第一个部分包含投票问题,也是用户投票的部分,另一部分是他们将看到投票结果的部分。
<asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0">
<asp:View ID="View1" runat="server">
<table>
<tr>
<td id="header">
POLL
</td>
</tr>
<tr>
<td id="head">
<asp:Label ID="lblHead" runat="server"></asp:Label>
</td>
</tr>
<tr>
<td>
<asp:RadioButtonList ID="rbQ" runat="server" Width="95%">
</asp:RadioButtonList>
</td>
</tr>
<tr>
<td id="footer">
<asp:Button ID="btnSubmit" runat="server"
OnClick="btnSubmit_Click" Text="Submit" />
</td>
</tr>
</table>
</asp:View>
<asp:View ID="View2" runat="server">
<asp:Xml ID="Xml1" runat="server" DocumentSource="~/App_Data/pollData.xml"
TransformSource="~/App_Data/pollView.xsl"></asp:Xml>
</asp:View>
</asp:MultiView>
编写代码
当 Web 表单首次加载时,我们使用 LinqToXml
从 XML 文件中获取数据。
if (!IsPostBack)
{
if (IsExist(GetIpAddress()))
MultiView1.ActiveViewIndex = 1;
else
{
MultiView1.ActiveViewIndex = 0;
pollInformation();
}
}
void pollInformation()
{
string path = Server.MapPath(@"App_Data/pollData.xml");
//input xml doc
XDocument myXml = XDocument.Load(path);
//get header
lblHead.Text = myXml.Element("Poll").Attribute("name").Value;
//get answers
foreach (var att in myXml.Element("Poll").Elements("answer"))
rbQ.Items.Add(att.Attribute("text").Value);
}
将文件加载到内存中后,使用 XDocument
,逐个;
- 我们将投票标题设置为
Label
控件的Text
属性 - 我们将问题(项目计数)作为
Item
添加到RadioButtonList
中
protected void btnSubmit_Click(object sender, EventArgs e)
{
string IpAddress = GetIpAddress();
if (rbQ.SelectedValue != string.Empty && !IsExist(IpAddress))
{
string path = Server.MapPath(@"App_Data/pollData.xml");
//input xml doc
XDocument myXml = XDocument.Load(path);
//get value of vote
int value = Convert.ToInt32(myXml
.Descendants("answer")
.Where(n => ((string)n.Attribute("text").Value ==
rbQ.SelectedValue)).Single().Value);
//increase value +1
value++;
//set new value of vote
myXml.Descendants("answer").Single(n => ((string)n.Attribute
("text").Value == rbQ.SelectedValue)).Value = value.ToString();
//save xml doc
myXml.Save(path);
//add ipaddress
AddIpAddress(IpAddress);
}
MultiView1.ActiveViewIndex = 1;
}
在投票部分,其呈现已完成,我们将所选问题所属的节点的值增加 1。为此,我们根据所属属性查询 radiobuttonlist
控件中已选项目的价值,我们将得到相关值。然后,我们再次保存 XML 数据。
使用 XSLT 的投票结果
现在,是时候查看投票结果了。我们正在展示基于以下想法的数据,如果存在 XML,则也有 XSLT。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:variable name="summ" select="sum(Poll/answer)"></xsl:variable>
<table>
<tr>
<td id="header" colspan="3">POLL RESULTS</td>
</tr>
<tr>
<td id="head" colspan="3">
<xsl:value-of select="Poll/@name"/>
</td>
</tr>
<xsl:for-each select="Poll/answer">
<tr>
<td width="120">
<xsl:value-of select="@text"/>
</td>
<td id="value">
%<xsl:value-of select="format-number(. * 100 div $summ,'0')"/>
</td>
<td width="100">
<xsl:variable name="innerSumm" select=". * 100 div $summ"></xsl:variable>
<img src="images/bar.png" height="10" width="{$innerSumm}%" />
</td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
毫无疑问,这里最重要的一部分是计算投票的百分比...
%<xsl:value-of select="format-number(. * 100 div $summ,'0')"/>
...并根据百分比确定投票图片的条形图。
<img src="images/bar.png" height="10" width="{$innerSumm}%" />
结果
我们已经看到,XML 和 XSLT 再次产生了很多实际结果。我们的目标不是编写太多的代码,而是有效地、适当地使用技术。
更新
- 防止多次投票