2014-11-14 129 views
0

我要读XML文档数据,是在这里:阅读的XMLDocument具有相同的元素名称

<root> 
    <cartype>Mercedes</cartype> 
    <production>2005</production> 
    <fuel>Diesel</fuel> 
    <color>Red</color> 
    <services> 
    <service> 
     <year>2006</year> 
     <km>47800</km> 
     <city>Stuttgart</city> 
    </service> 
    <service> 
     <year>2007</year> 
     <km>92125</km> 
     <city>FFM</city> 
    </service> 
    <service> 
     <km>180420</km> 
     <year>2009</year> 
     <city>Hannover</city> 
    </service> 
    </services> 
    <condition>Good</condition> 
</root> 

然后我读它是这样:

Dim cartype As String 
Dim fuel As String 
Dim production As String 
Dim color As String 
Dim serviceyear() As String = {"", "", ""} 
Dim servicekm() As String = {"", "", ""} 
Dim sevicecity() As String = {"", "", ""} 
Dim doc As XmlDocument = New XmlDocument() 

doc.Load("mercedes.xml") 
Dim root As XmlElement = doc.DocumentElement 

Dim node As XmlNode = root.SelectSingleNode("production") 
If Not node Is Nothing Then production = node.InnerText 

node = root.SelectSingleNode("cartype") 
If Not node Is Nothing Then cartype = node.InnerText 

node = root.SelectSingleNode("fuel") 
If Not node Is Nothing Then fuel = node.InnerText 

node = root.SelectSingleNode("color") 
If Not node Is Nothing Then color = node.InnerText 

node = root.SelectSingleNode("services/service/year") '' first service year 
If Not node Is Nothing Then serviceyear(0) = node.InnerText 

node = root.SelectSingleNode("services/service/year") '' second service year 
If Not node Is Nothing Then serviceyear(1) = node.InnerText 

具有独特的元素名称读节点是确定的,但我不知道如何读取数组中的所有“服务”,因为显示的代码只读取第一个服务。服务可能从0到未定义的数字。函数必须尽可能快,因为大量的xml必须在可能的时间内被减少。

回答

2

读取变量数<service>的元素,你将需要使用SelectNodes而不是SelectSingleNode

Dim services = root.SelectNodes("services/service") 

然后,您可以遍历<service>节点:

For Each service In services 
    If service("year") IsNot Nothing Then 
     Dim year = service("year").InnerText 
    End If 
Next 

个人而言,我会使用LINQ to XML解析文件(但这可能是因为我痴迷于LINQ的所有东西!)。结合VB.NET对XML Literals的支持,它使得一些非常漂亮的代码(恕我直言)。

这是一个完整的例子,你可以粘贴到LINQPad

Sub Main 
    ' Use XElememt.Load(fileName) to load from file 
    Dim xml = 
    <root> 
     <cartype>Mercedes</cartype> 
     <production>2005</production> 
     <fuel>Diesel</fuel> 
     <color>Red</color> 
     <services> 
      <service> 
       <year>2006</year> 
       <km>47800</km> 
       <city>Stuttgart</city> 
      </service> 
      <service> 
       <year>2007</year> 
       <km>92125</km> 
       <city>FFM</city> 
      </service> 
      <service> 
       <km>180420</km> 
       <year>2009</year> 
       <city>Hannover</city> 
      </service> 
     </services> 
     <condition>Good</condition> 
    </root> 
    Dim history = New ServiceHistory() With { 
     .CarType = xml.<cartype>.Value, 
     .Production = xml.<production>.Value, 
     .Fuel = xml.<fuel>.Value, 
     .Color = xml.<color>.Value, 
     .Condition = xml.<condition>.Value, 
     .Services = (
      From svc In xml.<services>.<service> 
      Select New Service() With { 
       .Year = svc.<year>.Value, 
       .KM = svc.<km>.Value, 
       .City = svc.<city>.Value 
      } 
     ).ToList() 
    } 
    history.Dump() 
End Sub 

' Define other methods and classes here 
Public Class ServiceHistory 
    Public Property CarType As String 
    Public Property Production As String 
    Public Property Fuel As String 
    Public Property Color As String 
    Public Property Condition As String 
    Public Property Services As List(Of Service) 
End Class 

Public Class Service 
    Public Property Year As String 
    Public Property KM As String 
    Public Property City As String 
End Class 

这给你以下几点:

LINQPad Results

+0

谢谢你马克非常教育答案和可行的,方便的解决方案。我更喜欢oldfashion的方式,它很好。只需要改变这一行:“对于每个服务作为XmlNode在服务中”可能是因为Option Strict开启。 – 2014-11-14 19:23:51

+0

很高兴有用。对于'作为XmlNode'部分,我总是有'Option Infer On'和'Option Strict On',以避免在严格打字的同时轻轻打字,所以我总是忘记在例子中明确表达 - 对此深表歉意。 – Mark 2014-11-14 19:34:09

0

尝试LINQ它会更容易解析XML: 它必须是类似的东西:

xelement = XElement.Load(file); 
services = xelement.Element("services").Elements("service");