日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

VB和VB.NET中的XML操作

 xiaoyi 2006-05-29


  概述:這篇文章為計(jì)劃將他們的應(yīng)用程序更新到Visual Basic.NET的微軟Visual Basic 開(kāi)發(fā)用戶提供一些關(guān)于XML的建議。主要包括Visual Basic 6和Visual Basic.NET對(duì)XML操作的不同之處,以及Visual Basic.NET關(guān)于這方面新增工具的應(yīng)用。 概述:這篇文章為計(jì)劃將他們的應(yīng)用程序更新到Visual Basic.NET的微軟Visual Basic 開(kāi)發(fā)用戶提供一些關(guān)于XML的建議。主要包括Visual Basic 6和Visual Basic.NET對(duì)XML操作的不同之處,以及Visual Basic.NET關(guān)于這方面新增工具的應(yīng)用。

  擴(kuò)展標(biāo)記語(yǔ)言XML是一種簡(jiǎn)單的數(shù)據(jù)存儲(chǔ)語(yǔ)言,使用一系列簡(jiǎn)單的標(biāo)記描述數(shù)據(jù),而這些標(biāo)記可以用方便的方式建立。XML的簡(jiǎn)單使其易于在任何應(yīng)用程序中讀寫數(shù)據(jù),這使XML很快成為數(shù)據(jù)交換的唯一公共語(yǔ)言,可以說(shuō),“沒(méi)有XML,就沒(méi)有編程的未來(lái)”。

  XML主要應(yīng)用在以下幾個(gè)方面:

  1. 設(shè)計(jì)標(biāo)記語(yǔ)言,如CML,MathML, WML等。

  2. 數(shù)據(jù)交換和數(shù)據(jù)整合,這是XML最激動(dòng)人心的應(yīng)用。

  3. 媒體無(wú)關(guān)的數(shù)據(jù)發(fā)布

  4. 智能代理和本地計(jì)算

  5. 精確搜索

  6. 文件保值

  XML的語(yǔ)法非常的簡(jiǎn)單,XML文檔由節(jié)點(diǎn)組成,使用打開(kāi)和關(guān)閉節(jié)點(diǎn)描述標(biāo)記,在格式上與HTML標(biāo)記非常相似,它們之間最大的不同是:XML中可以自由定義標(biāo)記名。比如下面的標(biāo)記就描述了一個(gè)主頁(yè)地址:

   <web>http://hongwanfu.126.com</web>

  注意,XML不用聲明標(biāo)記名就可以使用,而且,開(kāi)始和結(jié)束標(biāo)記必須相同,XML是識(shí)別大小寫的,所以標(biāo)記的大小寫也必須相同。

  節(jié)點(diǎn)標(biāo)記中可以包含屬性,比如:

<web type=”Homepage”>http://hongwanfu.126.com</web>
  
  代碼中Web節(jié)點(diǎn)包含屬性Type,其值為Homepage.

  如果不愿意在節(jié)點(diǎn)中包含一個(gè)值,那么可以不需要結(jié)束標(biāo)記,可以用在開(kāi)始標(biāo)記的后面加一個(gè)斜線來(lái)結(jié)束節(jié)點(diǎn),在下面的例子中,Web標(biāo)記的屬性就存儲(chǔ)了一個(gè)電話號(hào)碼,所以就不需要一個(gè)結(jié)束標(biāo)記:

<web type=”Homepage” url=”http://hongwanfu.126.com” />
 
  以上只是對(duì)XML文檔的簡(jiǎn)單描述,如何使用文檔中包含的信息,XML標(biāo)準(zhǔn)體系中有其他的配套標(biāo)準(zhǔn)。


在Visual Basic 6.0中操縱XML文件
2002-10-17· ·crystal編譯··yesky

  什么是XML

  擴(kuò)展標(biāo)記語(yǔ)言XML是一種簡(jiǎn)單的數(shù)據(jù)存儲(chǔ)語(yǔ)言,使用一系列簡(jiǎn)單的標(biāo)記描述數(shù)據(jù),而這些標(biāo)記可以用方便的方式建立,雖然XML占用的空間比二進(jìn)制數(shù)據(jù)要占用更多的空間,但XML極其簡(jiǎn)單易于掌握和使用。
  XML與Access,Oracle和SQL Server等數(shù)據(jù)庫(kù)不同,數(shù)據(jù)庫(kù)提供了更強(qiáng)有力的數(shù)據(jù)存儲(chǔ)和分析能力,例如:數(shù)據(jù)索引、排序、查找、相關(guān)一致性等,XML僅僅是展示數(shù)據(jù)。事實(shí)上XML與其他數(shù)據(jù)表現(xiàn)形式最大的不同是:他極其簡(jiǎn)單。這是一個(gè)看上去有點(diǎn)瑣細(xì)的優(yōu)點(diǎn),但正是這點(diǎn)使XML與眾不同。

  XML的簡(jiǎn)單使其易于在任何應(yīng)用程序中讀寫數(shù)據(jù),這使XML很快成為數(shù)據(jù)交換的唯一公共語(yǔ)言,雖然不同的應(yīng)用軟件也支持其它的數(shù)據(jù)交換格式,但不久之后他們都將支持XML,那就意味著程序可以更容易的與Windows、Mac OS, Linux以及其他平臺(tái)下產(chǎn)生的信息結(jié)合,然后可以很容易加載XML數(shù)據(jù)到程序中并分析他,并以XML格式輸出結(jié)果。

  XML的優(yōu)點(diǎn)

  我們談到XML長(zhǎng)于在不同的應(yīng)用程序之間交換數(shù)據(jù),XML文件也便于構(gòu)建小的數(shù)據(jù)庫(kù),不久以前,軟件都使用INI文件存儲(chǔ)配置信息、用戶參數(shù)以及其他信息,后來(lái)微軟引入了系統(tǒng)注冊(cè)表,接作微軟告訴我們不應(yīng)該再使用INI文件了,從那時(shí)起Visual Basic對(duì)INI文件的支持被削弱了。但不幸的是注冊(cè)表有幾個(gè)致命的缺點(diǎn):不是簡(jiǎn)單的文本文件,難于讀寫、可能會(huì)變得龐大和緩慢、如果注冊(cè)表不知何故出現(xiàn)問(wèn)題,將有可能造成系統(tǒng)死機(jī)。

  將配置信息放在XML文件中可以避免這些問(wèn)題,甚至可以將XML文件設(shè)置為一個(gè)共享文件,這樣在不同的計(jì)算機(jī)上的用戶就可以共享數(shù)據(jù),這是注冊(cè)表所不能比擬的。

  在被稱為下一代ASP的ASP.NET中可以在WEB頁(yè)中直接使用XML,你可以使用數(shù)據(jù)綁定控件直接綁定數(shù)據(jù)并自動(dòng)顯示。

  當(dāng)然也可以不選擇XML,使用文本文件、注冊(cè)表、數(shù)據(jù)庫(kù)都可以完成XML所能完成的任務(wù),XML只是你在數(shù)據(jù)存儲(chǔ)和恢復(fù)的另一種工具而已。

  XML語(yǔ)法簡(jiǎn)介

  XML的語(yǔ)法非常的簡(jiǎn)單,XML文檔由節(jié)點(diǎn)組成,使用打開(kāi)和關(guān)閉節(jié)點(diǎn)描述標(biāo)記,在格式上與HTML標(biāo)記非常相似,它們之間最大的不同是:XML中可以自由定義標(biāo)記名。比如下面的標(biāo)記就描述了一個(gè)電話號(hào)碼:

  <Phone>987-654-3210</Phone>

  而且不用聲明標(biāo)記名就可以使用。

  開(kāi)始和結(jié)束標(biāo)記必須相同,XML是識(shí)別大小寫的,所以標(biāo)記的大小寫也必須相同。比如上面的例子中以<Phone>標(biāo)記開(kāi)始就必須以</Phone>標(biāo)記結(jié)束,而不能是</phone>或</PHONE>

  節(jié)點(diǎn)標(biāo)記中可以包含屬性,比如下面的代碼中Phone節(jié)點(diǎn)包含屬性Type,其值為WorkFax:

 ?。糚hone Type="WorkFax">987-654-3210<Phone>

  如果不愿意在節(jié)點(diǎn)中包含一個(gè)值,那么可以不需要結(jié)束標(biāo)記,可以用在開(kāi)始標(biāo)記的后面加一個(gè)斜線來(lái)結(jié)束節(jié)點(diǎn),在下面的例子中,Phone標(biāo)記的Number屬性就存儲(chǔ)了一個(gè)電話號(hào)碼,所以就不需要一個(gè)結(jié)束標(biāo)記:

 ?。糚hone Type="WorkFax" Number="987-654-3210" />

  XML文檔的結(jié)構(gòu)是一個(gè)樹(shù)形等級(jí)結(jié)構(gòu)。文檔必須有一個(gè)唯一的根結(jié)點(diǎn),根節(jié)點(diǎn)包含所有其它節(jié)點(diǎn)。下面我們舉一個(gè)較為完整的例子:

<Addresses>
 <Entry Type="Personal">
 ?。糉irstName>Andy</FirstName>
  <LastName>Fickle</LastName>
 ?。糞treet>1234 Programmer Place</Street>
  <City>Bugsville</City>
 ?。糞tate>CO</State>
 ?。糧ip>82379</Zip>
 ?。糚hone Type="Home">354-493-9489</Phone>
?。?Entry>
?。糆ntry Type="Work">
  <FirstName>Betty</FirstName>
 ?。糒astName>Masterson</LastName>
 ?。糚hone Type="Work">937-878-4958</Phone>
 ?。糚hone Type="WorkFax">937-878-4900</Phone>
 </Entry>
 ...
</Addresses>

  注意相似的節(jié)點(diǎn)不需要包含相同的信息,例如第一個(gè)Entry節(jié)點(diǎn)包含了地址信息和家庭電話號(hào)碼,第二個(gè)Entry節(jié)點(diǎn)包含了Work和WorkFax電話號(hào)碼,而沒(méi)有包含第一個(gè)Entry節(jié)點(diǎn)包含的信息。

  XML工具

  如前面的例子顯示,XML語(yǔ)法是如此的簡(jiǎn)單以至于你可以在很短的時(shí)間作一個(gè)XML解析器,幸運(yùn)的是你不必這樣做,因?yàn)閄ML工具可以運(yùn)行在各種平臺(tái)上,包括可以安裝了Visual Basic的Windows。

  正是這些L工具而不是XML本身使XML變得更強(qiáng)大和復(fù)雜。不同的解析器使你可以某一時(shí)刻加載整個(gè)XML文檔或只加載某個(gè)節(jié)點(diǎn),與此相反,XML Writer 可以同時(shí)創(chuàng)建一個(gè)XML文檔和節(jié)點(diǎn)。

  DOM解析器使我們能夠很方便的加載、復(fù)制、排序、修改和存儲(chǔ)XML文件,遍歷節(jié)點(diǎn)獲得名稱或?qū)傩?,并給結(jié)果排序。雖然他們的功能沒(méi)有真正的關(guān)系數(shù)據(jù)庫(kù)強(qiáng)大,但DOM的這些特點(diǎn)依然非常有用。

  XSD可以定義XML文檔的格式,XSL擴(kuò)展樣式單定義了怎樣將XML文檔轉(zhuǎn)換成其他可以在WEB瀏覽器中瀏覽的文件格式,比如HTML文件。

  這些工具實(shí)際上比XML本身更復(fù)雜,所以所有講解XML的書(shū)籍都花了很大的篇幅解釋這些XML工具。但這超出了本文的范圍,有興趣的讀者可以參考有關(guān)資料。

  Visual Basic.Net提供了使用XML、XSL以及其他XML工具的完整工具。但不用等待VB.NET,微軟XML核心服務(wù)(MSXML)版本4.0提供了從Visual Basic6.0加載和存儲(chǔ)XML文檔的工具。

  在msdn.microsoft.com/xml/default.asp中下載最新版本的MSXML,并安裝在計(jì)算機(jī)上。在Visual Basic 6.0中使用Microsoft XML V4.0象引用其他對(duì)象一樣,首先在工程菜單中選擇引用菜單項(xiàng),選擇Microsoft V4.0,單擊OK,一切完成后就現(xiàn)在就可以在VB應(yīng)用程序中添加X(jué)ML對(duì)象了。

與Visual Basic .NET一起使用.NET Framework
2002-08-29· · ··Microsoft

  使用.NET Framework,Microsoft Visual Basic開(kāi)發(fā)人員可以創(chuàng)建健壯的、在先前的Visual Basic版本中很難編寫的應(yīng)用程序。本文將討論使用.NET Framework的好處,并且將包括一些功能強(qiáng)大的、Visual Basic開(kāi)發(fā)人員可以與該框架一起使用的特性,包括多線程和線程池(thread pooling)、Windows服務(wù)和文件系統(tǒng)監(jiān)控等。

  為什么使用框架

  單詞框架(framework)有幾種含意。在這種情況中,它指的是創(chuàng)建和運(yùn)行應(yīng)用程序的基礎(chǔ)。擁有這樣的基礎(chǔ)使得創(chuàng)建應(yīng)用程序變得更容易,而同時(shí)使用了一個(gè)一致的、簡(jiǎn)化的程序設(shè)計(jì)模型。

  作為一個(gè)Visual Basic 6.0開(kāi)發(fā)人員,你對(duì)于這種程序設(shè)計(jì)語(yǔ)言感覺(jué)很滿意,它使得創(chuàng)建各種應(yīng)用程序變得很容易。Visual Basic語(yǔ)言本身提供了固有的數(shù)據(jù)類型,如 Integer, Long和String,以及一些最常用的函數(shù),如字符串處理和數(shù)據(jù)類型轉(zhuǎn)換等。當(dāng)你的應(yīng)用程序變得更復(fù)雜時(shí),你可以使用Win32 API來(lái)完成標(biāo)準(zhǔn)的Visual Basic函數(shù)所不能實(shí)現(xiàn)的功能-如獲取任意的注冊(cè)鍵和數(shù)值。在許多情況中,你還可以使用COM(Component Object Model,組件對(duì)象模型)組件庫(kù)來(lái)擴(kuò)展應(yīng)用程序的功能;最明顯的例子是ADO(ActiveX Data Objects)庫(kù),你的應(yīng)用程序可以使用它來(lái)進(jìn)行數(shù)據(jù)訪問(wèn)。

  雖然Visual Basic足夠靈活,可以提供這些不同的可擴(kuò)展性機(jī)制,但這種靈活性仍然需要你學(xué)習(xí)幾種復(fù)雜的API體系結(jié)構(gòu)。你需要了解Win32如何工作,以及如何在Visual Basic中調(diào)用它們,這可能會(huì)是一個(gè)既費(fèi)時(shí)又容易出錯(cuò)的任務(wù)。你還需要了解如何在Visual Basic中使用各種COM組件,每個(gè)COM組件都有一個(gè)不同的對(duì)象模型。

  最后,當(dāng)你使用Win32 API、ADO,也可能使用許多其他COM組件,創(chuàng)建自己的Visual Basic應(yīng)用程序時(shí),你需要管理這些應(yīng)用程序的部署以及它們的相關(guān)性。一個(gè)典型的Visual Basic應(yīng)用程序的相關(guān)性列表所包括的遠(yuǎn)遠(yuǎn)多于Visual Basic運(yùn)行時(shí)(runtime);它必須包括應(yīng)用程序使用的所有對(duì)象庫(kù),如ADO 2.6。

  公共框架背后的想法是解決這些問(wèn)題,并使得用戶創(chuàng)建健壯的應(yīng)用程序變得更容易,而無(wú)需學(xué)習(xí)多種不同的API體系結(jié)構(gòu),并且無(wú)需部署和處理多種對(duì)象庫(kù)的版本問(wèn)題。

  什么是.NET Framework

  術(shù)語(yǔ).NET Framework指的是構(gòu)成Microsoft .NET平臺(tái)開(kāi)發(fā)基礎(chǔ)的一組技術(shù)。這一組中的關(guān)鍵技術(shù)是運(yùn)行時(shí)(runtime)和類庫(kù),如圖1所示。



圖 1. .NET Framework由.NET運(yùn)行時(shí)和類庫(kù)組成

  運(yùn)行時(shí)負(fù)責(zé)管理代碼,在執(zhí)行時(shí)向它提供服務(wù),這與Visual Basic 6.0運(yùn)行時(shí)的作用類似。.NET程序設(shè)計(jì)語(yǔ)言-包括Visual Basic .NET、Microsoft Visual C#、C++管理的擴(kuò)展,以及多種來(lái)自不同開(kāi)發(fā)商的程序設(shè)計(jì)語(yǔ)言-通過(guò)一組公共的統(tǒng)一類來(lái)利用各種服務(wù)和特性。

  .NET統(tǒng)一類提供了創(chuàng)建應(yīng)用程序的基礎(chǔ),而不管你使用何種語(yǔ)言。無(wú)論你只是簡(jiǎn)單地連接一個(gè)字符串,還是創(chuàng)建一個(gè)Windows服務(wù)或多層的基于網(wǎng)絡(luò)的應(yīng)用程序,你都要用到這些統(tǒng)一類。

  統(tǒng)一類為訪問(wèn)平臺(tái)的功能性提供了一種一致的方法。一旦你學(xué)會(huì)了使用類庫(kù),你就會(huì)發(fā)現(xiàn)所有任務(wù)都遵循同一個(gè)一致的體系結(jié)構(gòu)。要編寫自己的應(yīng)用程序,你無(wú)需學(xué)習(xí)和掌握不同的API體系結(jié)構(gòu)。

  由于.NET Framework,部署Visual Basic .NET應(yīng)用程序變得更容易了。與Visual Basic 6.0應(yīng)用程序不同,你無(wú)需配置各種相關(guān)性,如單獨(dú)的數(shù)據(jù)訪問(wèn)庫(kù)、XML語(yǔ)法分析器和網(wǎng)絡(luò)API,因?yàn)樗羞@些功能都是.NET Framework的組成部分。

  通過(guò)在統(tǒng)一的、集成的框架上創(chuàng)建自己的應(yīng)用程序,你可以實(shí)現(xiàn)學(xué)習(xí)這種框架所花費(fèi)時(shí)間的最大回報(bào),并且你將擁有更多容易部署和使用的健壯的應(yīng)用程序。

Visual Basic.NET快速開(kāi)發(fā)MIS系統(tǒng)
2002-11-29· ·黎宇 ··yesky


  【摘 要】 本文介紹微軟最新技術(shù)Visual Basic.NET在數(shù)據(jù)庫(kù)開(kāi)發(fā)方面的應(yīng)用。結(jié)合數(shù)據(jù)庫(kù)系統(tǒng)開(kāi)發(fā)的知識(shí),介紹了物理表操作的方法,利用Visual Basic.NET的面向?qū)ο蟮奶卣?,利用類的繼承知識(shí),簡(jiǎn)化了數(shù)據(jù)庫(kù)系統(tǒng)開(kāi)發(fā)過(guò)程。

  引言

  以前版本的Visual Basic雖然號(hào)稱自己是一種OOP(面向?qū)ο螅┚幊陶Z(yǔ)言,但卻不是一個(gè)地地道道的OOP編程語(yǔ)言,最多只是半個(gè)面向?qū)ο蟮木幊陶Z(yǔ)言。但Visual Basic.NET已經(jīng)是一種完全的面向?qū)ο蟮木幊陶Z(yǔ)言。他支持面向?qū)ο蟮乃谢咎卣鳎豪^承、多態(tài)和重載。這使得以前在Visual Basic中很難或根本實(shí)現(xiàn)不了的問(wèn)題,在Visual Basic.NET中可以順利的用簡(jiǎn)單的方法實(shí)現(xiàn)。

  自定義數(shù)據(jù)操作類

  定義一個(gè)數(shù)據(jù)訪問(wèn)的基類,并編寫有關(guān)數(shù)據(jù)庫(kù)操作的必要方法。

  定義一個(gè)數(shù)據(jù)訪問(wèn)類,類名為CData。定義連接Oracle數(shù)據(jù)庫(kù)的方法ConnOracle,獲取數(shù)據(jù)集的方法GetDataSet, 獲取物理表的方法GetDataTable, 向物理表中插入一行數(shù)據(jù)的方法Insert, 向物理表中刪除數(shù)據(jù)的方法Delete, 向物理表中更新數(shù)據(jù)的方法Update。其實(shí)現(xiàn)方法不是本文的重點(diǎn),在此僅給出代碼,不作詳細(xì)分析。代碼如下:

Public Class CDataBase
Dim OleCnnDB As New OleDbConnection()

‘連接Oracle數(shù)據(jù)庫(kù),ServerName:服務(wù)器名,UserId:用戶名,UserPwd:用戶密碼
Public Function ConnOracle(ByVal ServerName As String, ByVal UserId As String, ByVal UserPwd As String) As OleDbConnection

 Dim OleCnnDB As New OleDbConnection()
 With OleCnnDB
  .ConnectionString = "Provider=MSDAORA.1;Password=‘" & UserPwd & "‘;User ID=‘" & UserId & "‘;Data Source=‘" & ServerName & "‘"
  Try
   .Open()
  Catch er As Exception
   MsgBox(er.ToString)
  End Try
 End With
 mOleCnnDB = OleCnnDB
 Return OleCnnDB
End Function

‘獲取數(shù)據(jù)集。TableName:表名,strWhere:條件
Public Overloads Function GetDataSet(ByVal TableName As String, ByVal strWhere As String) As DataSet

 Dim strSql As String
 Dim myDataSet As New DataSet()
 Dim myOleDataAdapter As New OleDbDataAdapter()

 myOleDataAdapter.TableMappings.Add(TableName, TableName)
 strSql = "SELECT * FROM " & TableName & " where " & strWhere

 myOleDataAdapter.SelectCommand = New OleDbCommand(strSql, mOleCnnDB)
 Try
  myOleDataAdapter.Fill(myDataSet)
 Catch er As Exception
  MsgBox(er.ToString)
 End Try
 Return myDataSet
End Function

‘獲取物理表。TableName:表名
Public Overloads Function GetDataTable(ByVal TableName As String) As DataTable
 Dim myDataSet As New DataSet()
 myDataSet = GetDataSet(TableName)
 Return myDataSet.Tables(0)
End Function

‘獲取物理表。TableName:表名,strWhere:條件
Public Overloads Function GetDataTable(ByVal TableName As String, ByVal strWhere As String) As DataTable

 Dim myDataSet As New DataSet()
 myDataSet = GetDataSet(TableName, strWhere)
 Return myDataSet.Tables(0)
End Function

 ‘向物理表中插入一行數(shù)據(jù)。TableName:表名,Value:行數(shù)據(jù),BeginColumnIndex:開(kāi)始列
Public Overloads Function Insert(ByVal TableName As String, ByVal Value As Object, Optional ByVal BeginColumnIndex As Int16 = 0) As Boolean

 Dim myDataAdapter As New OleDbDataAdapter()
 Dim strSql As String
 Dim myDataSet As New DataSet()
 Dim dRow As DataRow
 Dim i, len As Int16

 strSql = "SELECT * FROM " & TableName
 myDataAdapter.SelectCommand = New OleDbCommand(strSql, mOleCnnDB)
 Dim custCB As OleDbCommandBuilder = New OleDbCommandBuilder(myDataAdapter)
 myDataSet.Tables.Add(TableName)
 myDataAdapter.Fill(myDataSet, TableName)
 dRow = myDataSet.Tables(TableName).NewRow
 len = Value.Length
 For i = BeginColumnIndex To len - 1
  If Not (IsDBNull(Value(i)) Or IsNothing(Value(i))) Then
   dRow.Item(i) = Value(i)
  End If
 Next
 myDataSet.Tables(TableName).Rows.Add(dRow)
 Try
  myDataAdapter.Update(myDataSet, TableName)
 Catch er As Exception
  MsgBox(er.ToString)
  Return False
 End Try
 myDataSet.Tables.Remove(TableName)
 Return True
End Function

‘更新

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多