65.9K
CodeProject 正在变化。 阅读更多。
Home

Treeview - 使用 JavaScript、XSL 和 .NET 创建文件夹结构树形视图

starIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIconemptyStarIcon

1.87/5 (7投票s)

2007年2月19日

7分钟阅读

viewsIcon

48328

downloadIcon

493

通过 ASP.NET 生成动态 XML 来实时创建文件夹结构的树形视图,该 XML 使用 XSLT 进行转换,并通过 JavaScript 跟随用户导航。

引言

这是我提交到 CodeProject 的第一篇文章。我关注了三个多月,觉得大家提交文章的方式很有意思。我认为现在是时候提交一篇对初级开发者有帮助的文章了。我在这里介绍的文章涉及 VB 编码、XML 生成、XSLTJavaScript 的使用。

在动手编写代码之前,我想让您对本文的内容有一个概览。

有一个需求是显示一个非常不稳定的文件夹结构树形视图(意味着文件夹结构会发生变化)。每当用户访问页面时,他都必须看到系统中(服务器上)最新的文件夹、文档等。为了满足这个需求,我使用了在用户访问页面时实时生成的 XML,并使用 XSLT 和 JavaScript 来美化前端,以便在前端跟随用户的导航。我将结合代码解释所使用的对象。

使用代码

跟随代码的先决条件是:对 JavaScript、XSLT 有一点点了解,以及在 Visual Basic 方面有更丰富的经验。
首先,我们来看看这个应用程序中使用的命名空间。



imports system.xml
imports system.xml.xsl
imports system.text
imports system.io

这些命名空间用于访问系统目录对象和 XML 对象。
(文件路径和其他变量的命名约定尚未标准化)
Dim tw As XmlTextWriter
tw = New XmlTextWriter("C:\\test\test12345" & ".xml", _
New System.Text.UTF8Encoding())

tw.Formatting = Formatting.Indented
'tw.Indentation = 4

' Write out the header information
tw.WriteStartDocument()
' Starting the xml with tag name "folders". You can change it to other names, 'but change correspondingly in the xslt file as well.
tw.WriteStartElement("FOLDERS")' Starting the xml with tag name "folder". You can change it to other names, 'but change correspondingly in the xslt file as well.
tw.WriteStartElement("FOLDER")
tw.WriteAttributeString("name", "Knowledge Tree")
tw.WriteStartElement("FOLDER")
tw.WriteAttributeString("name", "Certification Material")

在上面的代码中,我们声明了一个 xmltextwriter 类的对象,它接受一个 XML 文件位置作为参数(构造函数)。这个对象具有 formatting 和 indentation 等属性,用于生成版本 1 并且编码为 "utf-8" 的有效 XML。通过 'writestartdocument' 方法开始 XML 文档。在我们深入之前,我将解释 xmltextwriter 的各种方法。从 WriteElementString 开始,它会在标签之间输出文本(<title>Enter status of bug for search</title>)。它接受两个参数:标签名称和要显示的文本(tw.WriteElementString("title", "Enter status of bug for search"))。当然,我们在代码中没有使用它,但它很有用。至于 WriteStartElement,我们可以用它开始一个新的标签(<folder>)。必须有一个对应的结束标签,使用 writeendelement(</folder>)。这个标签非常巧妙:如果这个标签没有任何子元素(另一个 writestartelement),它将是一个自闭合标签。如果它有另一个 writestartelement(在 writeendelement 之前),它将成为父标签。

我使用递归函数来遍历目录。下面的函数不言自明,它会不断调用自身,直到 FileSystemInfo 不是目录(FileSystemInfo.name <> directory)为止,否则(.doc、.txt)它将作为叶子节点结束。




Function fileinfo(ByVal strfilepath As String) As Collection
Dim colinner As New Collection
' Declaring DirectoryInfo object to get the file information stored 'in the system.
Dim dfinner As DirectoryInfo
' Passing the Parent file path (in which other files are stored), 'giving all access to the parent directory in order to avoid security 'exceptions.
dfinner = New DirectoryInfo(strfilepath)
Dim fsiinner As FileSystemInfo
For Each fsiinner In dfinner.GetFileSystemInfos
' Collecting all directory information present.
colinner.Add(fsiinner)

Next
Dim countinner As Integer = colinner.Count()
Dim tempdocinner As Integer = 0
For tempdocinner = 1 To countinner
Dim strtest1
strtest1 = colinner.Item(tempdocinner)
' Retrieving the type of elements stored in the collection.
Dim strtype As Type = strtest1.GetType()
If strtype.Name = "DirectoryInfo" Then
Dim strfilename As DirectoryInfo = colinner.Item(tempdocinner)
' Starting the xml with tag "folder".
' If you change this tag name, then change it in the xslt file as well.
tw.WriteStartElement("FOLDER")
tw.WriteAttributeString("name", prodnode.Text)

Dim strpathtemp = strfilepath & strtest1.name & "/"
' Since it is a directory, calling the function fileinfo (with the file 'path as an argument).
fileinfo(strpathtemp)
tw.WriteEndElement()
Else
' Coming to the else part when the GetType of the collection (
colinner) is not a 'directory.
' It means some .doc or .pdf or .ppt etc.
Dim files As FileInfo
files = colinner.Item(tempdocinner)
Dim strpath As String = files.FullName
prodnode = New TreeNode
prodnode.Text = files.Name
Dim strdocname As String = prodnode.Text
tw.WriteStartElement("KEY")
tw.WriteAttributeString("name", prodnode.Text)
tw.WriteAttributeString("path", strpath)

tw.WriteEndElement()

nodeSupp.ChildNodes.Add(prodnode)
End If
'tw.WriteEndElement()
Next

Return colinner
End Function

接下来,关于 IO 对象,我将结合代码进行阐述(抱歉我急于遵循编码标准)。



Dim strfileinfopath As String = System.AppDomain.CurrentDomain.BaseDirectory & "docs/"
Dim df As DirectoryInfo
' Getting the directory information by passing the directory path as 'argument.
df = New DirectoryInfo(strfileinfopath)
Dim fsi As FileSystemInfo
Dim col As New Collection
Dim colfilepath As New Collection
Dim colfilename As New Hashtable
' Collecting all filesystem information present in the parent folder.

For Each fsi In df.GetFileSystemInfos
Dim shi = fsi
col.Add(fsi)
Next
Dim docfilescoun As Integer = col.Count()
Dim tempdoc As Integer = 0
Dim strfileinfo As DirectoryInfo
If docfilescoun > 0 Then
For tempdoc = 1 To docfilescoun
strfileinfo = col.Item(tempdoc)
Dim strtest
strtest = col.Item(tempdoc)
' Getting the type of the items in the collection (
col)
Dim strtype As Type = strtest.GetType
' If the type is DirectoryInfo, continue (repeating the process of 'checking the subfolders) since it may contain subfolders by 'calling the function fileinfo with the path of the folder to be checked.
If strtype.Name = "DirectoryInfo" Then
Dim filecollection As New Collection
' Using the FullName property of the FileInfo object to get the path of 'that file.
Dim strfullname As String = strfileinfo.FullName
Dim strfilename1 As String = strfileinfo.Name
Dim strfileinnerpath As String = System.AppDomain.CurrentDomain.BaseDirectory & "docs/" & strfilename1 & "/"
' Starting the xml with tag name "folder". You can change it to other names, 'but change correspondingly in the xslt file as well.
tw.WriteStartElement("FOLDER")
tw.WriteAttributeString("name", strfilename1)

' testmaterial is my local directory folder.

If strfileinfo.Name <> "
testmaterial " Then
filecollection = fileinfo(strfileinnerpath)
End If
tw.WriteEndElement()
Else
' Coming to the else part means the item in the collection (col) is not a 'directory. It is of .doc or .pdf or .ppt etc.
Dim filename As FileInfo
filename = col.Item(tempdoc)
Dim strfull As String = filename.FullName
tw.WriteStartElement("
KEY")
tw.WriteAttributeString("
name", filename.Name)
tw.WriteAttributeString("
Path", strfull)
tw.WriteEndElement()
End If
Next
' Closing all the nodes correspondingly.
tw.WriteEndElement()
tw.WriteEndElement()
tw.WriteEndElement()
tw.WriteEndDocument()
' Disposing all the objects of xml.
tw.Flush()
tw.Close()
End If

Starting with System.AppDomain.CurrentDomain.BaseDirectory which returns the path of the base directory of your application as it is developed in vs.net. In this case, it returns "C://inetpub/wwwroot/treeview". Coming to the DirectoryInfo class, which returns all the directory information about the path passed as an argument.

In this for loop, "fsi" is an object of the FileSystemInfo class, where GetFileSystemInfos is a method of DirectoryInfo that returns file or directory information for each FileSystemInfo type.




For Each fsi In df.GetFileSystemInfos
Dim shi = fsi
col.Add(fsi)
下一篇

Here we are calling the fileinfo function because it is a directory (I mean it is a file that may contain subfolders, which in turn contain documents or subfolders).

filecollection = fileinfo(strfileinnerpath)

Coming to the crux: applying XSLT to XML.

Dim doc As New XmlDocument()

doc.Load(Server.MapPath("test12345.xml"))

Dim t As New XslTransform()
t.Load(Server.MapPath("images/XSLTFile1.xslt"))
Dim sb As New StringBuilder()
Dim writer As TextWriter
writer = New StringWriter(sb)

'vvvvvvimp
' If the framework is older, add "nothing" as one more argument to 'the following t.transform, like t.Transform(doc, Nothing, writer, Nothing)
'vvvvimp


t.Transform(doc, Nothing, writer)
Label1.Text = sb.ToString()
}



In the above block of code, we load the XML document using Server.MapPath and apply XSLT to XML using the XslTransform class.



我将用提供代码(这段代码需要更多地解析为 XML)来结束本文。如果您知道如何读取 XML 文档或对 XmlTextReader 类有所了解,则可以跳过此部分。



Dim oRead As XmlTextReader
Dim cou As Integer = 1

试试
oRead = New XmlTextReader("C:\inetpub\wwwroot\test\test12345.xml")
Do While oRead.Read
oRead.MoveToContent()
If oRead.Name.Equals("KEY") Then

If oRead.GetAttribute("name").ToString = lsStatus Then
Dim strpath As String = oRead.GetAttribute("path")
Dim stractpath = Split(strpath, "test\")
Dim stractpath1 = stractpath(1)
' Redirecting to viewfile.aspx for viewing the file selected with 'path as querystring.
Response.Redirect("viewfile.aspx?filename=" + stractpath1)
End If
End If

循环

我在这里结束本文,其中包含的整个代码只涉及三个对象:

1. directoryinfo
2. xmltextwriter
3. xsltransform
4. xmltextreader

我的意思是,没有什么可以吓倒的,只是围绕这四个对象进行操作,并递归地调用一个函数。

关于下载。

zip 文件中提供的应用程序与 v1.1 和 Visual Studio 2003 兼容。
© . All rights reserved.