2015年6月27日 星期六

ASP.NET 為自己的系統建立XML檔

參考資料1:[VB.NET]XML的建立與讀取
參考資料2:VB.NET中操作xml文件(插入節點、修改、刪除)

為自己的系統建立XML檔,可以將一些系統的設定寫在XML檔中,例如:路徑、時間等;如此一來就不用因為只是為了一些設定,對資料庫建立一個資料表存取,而且倘若如果沒有資料庫,我們也可以做系統的設定。

此篇針對XML做簡單的讀取、建立、修改、刪除某一個節點,作簡單的應用。

sysconfig.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<system_config>
 <a1 path="C:\temp\a1\" creation_time="2015/06/28 13:38:52" />
 <a1attr path="C:\temp\a1\attr\" creation_time="2015/06/28 13:38:52" />
</system_config>
Default.aspx
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="WebApplication_testxml._Default" %>
<!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>測試xml</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" Text="建立xml" /><br/>
<asp:Button ID="Button2" runat="server" Text="讀取xml" /><br/>
<asp:Button ID="Button3" runat="server" Text="修改xml" /><br/>
<asp:Button ID="Button5" runat="server" Text="刪除某一個節點" />此處刪除a1attr子節點<br/>
<asp:Button ID="Button4" runat="server" Text="重新建立xml" />
<asp:Label ID="Label1" runat="server" ></asp:Label>
</div>
</form>
</body>
</html>
Default.aspx.vb
Imports System.Xml
Imports System.IO
Partial Public Class _Default
Inherits System.Web.UI.Page
Dim xdoc As XmlDocument
Dim str_path As String = String.Empty

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
str_path = Server.MapPath("~/xml/")
If Directory.Exists(str_path) = False Then '目錄不存在
Directory.CreateDirectory(str_path) '建立目錄
End If
End If
End Sub

Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
Dim xElement As XmlElement
Dim xElement2 As XmlElement
Try
str_path = Server.MapPath("~/xml/") & "sysconfig.xml"
If File.Exists(str_path) = True Then
'已存在
Label1.Text = str_path & " 檔案已存在"
Else
'不存在
'建立一個 XmlDocument 物件並加入 Declaration
xdoc = New XmlDocument
xdoc.AppendChild(xdoc.CreateXmlDeclaration("1.0", "UTF-8", "yes"))
'建立根節點物件並加入 XmlDocument 中 (第0層)
xElement = xdoc.CreateElement("system_config")

xdoc.AppendChild(xElement)
'在system_config下寫入一個節點名稱為a1(第1層)
xElement2 = xdoc.CreateElement("a1")
xElement2.SetAttribute("path", "C:\temp\a1\")
xElement2.SetAttribute("creation_time", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"))
xElement.AppendChild(xElement2)
xElement2 = xdoc.CreateElement("a1attr")
xElement2.SetAttribute("path", "C:\temp\a1\attr\")
xElement2.SetAttribute("creation_time", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"))
xElement.AppendChild(xElement2)
xdoc.Save(str_path)
Label1.Text = "建立完成,檔案儲存在" & str_path
End If

Catch ex As Exception
Label1.Text = ex.Message & System.Environment.NewLine & ex.StackTrace
End Try

End Sub

Protected Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button2.Click
Dim str_read As String = String.Empty
Dim xRoot As XmlNode
Dim xUsersNode As XmlNode
Dim xElement As XmlElement
Try
str_path = Server.MapPath("~/xml/") & "sysconfig.xml"
If File.Exists(str_path) = True Then
'存在,就讀取
xdoc = New XmlDocument
'讀取XML
xdoc.Load(str_path)
xRoot = CType(xdoc.DocumentElement, XmlNode)

'取得節點[a1]
xUsersNode = xRoot.SelectSingleNode("a1")
xElement = CType(xUsersNode, XmlElement)
str_read = str_read & "a1 路徑:" & xElement.GetAttribute("path") & "<br/>"
str_read = str_read & "a1 建立時間:" & xElement.GetAttribute("creation_time") & "<br/>"

'取得節點[a1attr]
xUsersNode = xRoot.SelectSingleNode("a1attr")
xElement = CType(xUsersNode, XmlElement)
str_read = str_read & "a1attr 路徑:" & xElement.GetAttribute("path") & "<br/>"
str_read = str_read & "a1attr 建立時間:" & xElement.GetAttribute("creation_time") & "<br/>"

Label1.Text = str_read

Else
'不存在
Label1.Text = "請先在" & str_path & " 建立xml"
End If
Catch ex As Exception
Label1.Text = ex.Message & System.Environment.NewLine & ex.StackTrace & "<br/>" & str_path
End Try

End Sub

Protected Sub Button3_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button3.Click
Dim xRoot As XmlNode
Dim xUsersNode As XmlNode
Dim xElement As XmlElement
Try
str_path = Server.MapPath("~/xml/") & "sysconfig.xml"
If File.Exists(str_path) = True Then
xdoc = New XmlDocument
'讀取
xdoc.Load(str_path)
xRoot = CType(xdoc.DocumentElement, XmlNode)
'取得節點[a1]
xUsersNode = xRoot.SelectSingleNode("a1")
xElement = CType(xUsersNode, XmlElement)
'修改a1 creation_time的值
xElement.SetAttribute("creation_time", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")) '.GetAttribute("creation_time")

xdoc.Save(str_path)
Label1.Text = "修改完成"
Else
Label1.Text = "檔案不存在無法修改,請先建立xml檔"
End If
Catch ex As Exception
Label1.Text = ex.Message & System.Environment.NewLine & ex.StackTrace & "<br/>" & str_path
End Try

End Sub

Protected Sub Button4_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button4.Click
'重新建立,跟建立很像,就是拿掉判斷檔案存不存在,直接把檔案附蓋掉
Dim xElement As XmlElement
Dim xElement2 As XmlElement
Try
str_path = Server.MapPath("~/xml/") & "sysconfig.xml"
'建立一個 XmlDocument 物件並加入 Declaration
xdoc = New XmlDocument
xdoc.AppendChild(xdoc.CreateXmlDeclaration("1.0", "UTF-8", "yes"))
'建立根節點物件並加入 XmlDocument 中 (第0層)
xElement = xdoc.CreateElement("system_config")

xdoc.AppendChild(xElement)
'在system_config下寫入一個節點名稱為a1(第1層)
xElement2 = xdoc.CreateElement("a1")
xElement2.SetAttribute("path", "C:\temp\a1\")
xElement2.SetAttribute("creation_time", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"))
xElement.AppendChild(xElement2)
xElement2 = xdoc.CreateElement("a1attr")
xElement2.SetAttribute("path", "C:\temp\a1\attr\")
xElement2.SetAttribute("creation_time", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"))
xElement.AppendChild(xElement2)
xdoc.Save(str_path)
Label1.Text = "建立完成,檔案儲存在" & str_path
Catch ex As Exception
Label1.Text = ex.Message & System.Environment.NewLine & ex.StackTrace
End Try
End Sub

Protected Sub Button5_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button5.Click
Dim xRoot As XmlNode
Dim xUsersNode As XmlNode
Dim xElement As XmlElement
Try
str_path = Server.MapPath("~/xml/") & "sysconfig.xml"
If File.Exists(str_path) = True Then
xdoc = New XmlDocument
'讀取
xdoc.Load(str_path)
xRoot = CType(xdoc.DocumentElement, XmlNode)
'取得節點[a1]
xUsersNode = xRoot.SelectSingleNode("a1attr")
If Not xUsersNode Is Nothing Then
'存在
xRoot.RemoveChild(xUsersNode) '刪除a1attr子節點
'========分隔線=========
'如果要刪除,子節點全部的屬性,請將下方註解拿掉
'xElement = CType(xUsersNode, XmlElement)
'xElement.RemoveAll()
'========分隔線=========
'如果要刪除某個屬性,請將下方註解拿掉
'xElement = CType(xUsersNode, XmlElement)
'xElement.RemoveAttribute("creation_time") '刪除creation_time屬性
'========分隔線=========
xdoc.Save(str_path)
Label1.Text = "刪除完成"
Else
Label1.Text = "a1attr子節點 不存在"
End If
Else
Label1.Text = "檔案不存在無法刪除節點,請先建立xml檔"
End If
Catch ex As Exception
Label1.Text = ex.Message & System.Environment.NewLine & ex.StackTrace & "<br/>" & str_path
End Try
End Sub
End Class

2015年6月24日 星期三

VB.NET TextBox1跨執行緒作業無效

參考資料:vb.net-跨執行緒作業無效

因在執行緒中會有好幾個地方會呼叫TB_keyvalue方法,在呼叫的過程中,會變更TextBox1的值,此時會發生跨執行緒作業無效的問題;我修改了上方參考資料連結的程式碼,如下...

Private Delegate Sub UpdateUICB(ByVal TB1 As System.Windows.Forms.TextBox, ByVal str_ivalue As String, ByVal add_dt As Integer)

Sub TB_keyvalue(ByVal TB1 As System.Windows.Forms.TextBox, ByVal str_ivalue As String, Optional ByVal add_dt As Integer = 1)
 Dim str_dtime As String = String.Empty
 If add_dt = 1 Then
  str_dtime = "[" & DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") & "] "
 End If
 If Me.InvokeRequired() Then
  '你可以想像成,將TB_keyvalue方法指定給UpdateUICB
  Dim cb As New UpdateUICB(AddressOf TB_keyvalue)
  '當跑到Invoke時,你可以想像成程式碼去呼叫UpdateUICB,並把參數傳給它,此時就等於程式碼又去呼叫TB_keyvalue方法
  Me.Invoke(cb, TB1, str_dtime & str_ivalue, add_dt)
 Else
  If TB1.Text = "" Then
   TB1.Text = str_dtime & str_ivalue
  Else
   TB1.Text = str_dtime & str_ivalue & vbCrLf & TB1.Text
  End If
 End If
End Sub

P.S 我直接把我的想法寫在註解中,如有錯誤請指正,或想幫忙補充的,歡迎留言補充,謝謝。