[英]Traversing through XML
我有以下 XML 文件:
<Tournament TeamPlayers="1">
<Teams>
<Team>
<TeamID>0</TeamID>
<TeamName>Sample</TeamName>
<Status>10</Status>
<Memo>Sample Team</Memo>
<ByeRounds>0</ByeRounds>
<Players>
<Player>
<MemberNumber>1</MemberNumber>
<MemberName>Dummy</MemberName>
<PlayerFirstName>Test</PlayerFirstName>
<PlayerLastName>User</PlayerLastName>
<SeatOrder>A</SeatOrder>
</Player>
<Player>
<MemberNumber></MemberNumber>
<MemberName></MemberName>
<PlayerFirstName></PlayerFirstName>
<PlayerLastName></PlayerLastName>
<SeatOrder>B</SeatOrder>
</Player>
<Player>
<MemberNumber></MemberNumber>
<MemberName></MemberName>
<PlayerFirstName></PlayerFirstName>
<PlayerLastName></PlayerLastName>
<SeatOrder>C</SeatOrder>
</Player>
</Players>
</Team>
</Teams>
</Tournament>
這個想法是我循環遍歷<Players>
塊並將那里的數據添加到類數據的持有者中。 但是,當我運行以下代碼時,看起來它正在生成 Inner Players 字段的內容,VS 停止警告它為空:
Dim teamNodes As XmlNodeList = xmlDoc.DocumentElement.SelectNodes("/Tournament/Teams/Team")
Dim lstOutputTeams As New List(Of TournamentTeam)
' Check the atrribute of "TeamPlayers" in the root.
'Dim intExpectedPlayers As Integer = xmlDoc.Attributes("/").Value
Dim intExpectedPlayers As Integer = xmlDoc.SelectSingleNode("/Tournament").Attributes("TeamPlayers").Value
For Each node As XmlNode In teamNodes
Dim tpPlayerA As New PlayerInfo
Dim tpPlayerB As New PlayerInfo
Dim tpPlayerC As New PlayerInfo
Dim playerNodes As XmlNodeList = node.SelectNodes("Players")
For Each innerNode As XmlNode In playerNodes
Dim tpPlayer As PlayerInfo = New PlayerInfo With {
.strMembershipName = innerNode.SelectSingleNode("MemberName").InnerText,
.strMembershipNo = innerNode.SelectSingleNode("MemberNumber").InnerText,
.strPlayerFirstName = innerNode.SelectSingleNode("PlayerFirstName").InnerText,
.strPlayerLastName = innerNode.SelectSingleNode("PlayerLastName").InnerText,
.strSeatOrder = innerNode.SelectSingleNode("SeatOrder").InnerText
}
Select Case tpPlayer.strSeatOrder
Case "A"
tpPlayerA = tpPlayer
Case "B"
tpPlayerB = tpPlayerB
Case "C"
tpPlayerC = tpPlayerC
End Select
Next
lstOutputTeams.Add(New TournamentTeam() With {
.strTeamName = node.SelectSingleNode("TeamName").InnerText,
.intTeamID = node.SelectSingleNode("TeamID").InnerText,
.intByeRounds = node.SelectSingleNode("ByeRounds").InnerText,
.intStatus = node.SelectSingleNode("Status").InnerText,
.strMemo = node.SelectSingleNode("Memo").InnerText,
.tpPlayerA = tpPlayerA,
.tpPlayerB = tpPlayerB,
.tpPlayerC = tpPlayerC}
)
Next
特別是,錯誤是: System.NullReferenceException: 'Object reference not set to an instance of an object.'
. 我不確定空引用發生在哪里。 (斷點將其放置在Dim tpPlayer As Player Info
行。
您的Select Case
正在為自己分配變量,這可能會讓您感到悲傷:
Select Case tpPlayer.strSeatOrder
Case "A"
tpPlayerA = tpPlayer
Case "B"
tpPlayerB = tpPlayerB
Case "C"
tpPlayerC = tpPlayerC
End Select
每個的 RHS 應該只是tpPlayer
。
您通過執行以下操作導致了此錯誤:
Dim tpPlayerA As New PlayerInfo
Dim tpPlayerB As New PlayerInfo
Dim tpPlayerC As New PlayerInfo
你應該這樣做:
Dim tpPlayerA As PlayerInfo
Dim tpPlayerB As PlayerInfo
Dim tpPlayerC As PlayerInfo
這是您的代碼在XDocument
中的樣子。 干凈多了。
Dim intExpectedPlayers As Integer = CInt(xd.Root.Attribute("TeamPlayers"))
Dim lstOutputTeams As List(Of TournamentTeam) = _
( _
From team In xd.Root.Element("Teams").Elements("Team") _
Let players = team.Element("Players").Elements("Player").Select(Function(player) _
New PlayerInfo() With _
{
.strMembershipName = player.Element("MemberName").Value,
.strMembershipNo = player.Element("MemberNumber").Value,
.strPlayerFirstName = player.Element("PlayerFirstName").Value,
.strPlayerLastName = player.Element("PlayerLastName").Value,
.strSeatOrder = player.Element("SeatOrder").Value
}).ToDictionary(Function(x) x.strSeatOrder) _
Select New TournamentTeam() With _
{
.intTeamID = CInt(team.Element("TeamID")),
.strTeamName = CStr(team.Element("TeamName")),
.intStatus = CInt(team.Element("Status")),
.strMemo = CStr(team.Element("Memo")),
.intByeRounds = CInt(team.Element("ByeRounds")),
.tpPlayerA = players("A"),
.tpPlayerB = players("B"),
.tpPlayerC = players("C")
} _
).ToList()
這是我用於測試的xd
的創建:
Dim xd = XDocument.Parse("<Tournament TeamPlayers=""1"">
<Teams>
<Team>
<TeamID>0</TeamID>
<TeamName>Sample</TeamName>
<Status>10</Status>
<Memo>Sample Team</Memo>
<ByeRounds>0</ByeRounds>
<Players>
<Player>
<MemberNumber>1</MemberNumber>
<MemberName>Dummy</MemberName>
<PlayerFirstName>Test</PlayerFirstName>
<PlayerLastName>User</PlayerLastName>
<SeatOrder>A</SeatOrder>
</Player>
<Player>
<MemberNumber></MemberNumber>
<MemberName></MemberName>
<PlayerFirstName></PlayerFirstName>
<PlayerLastName></PlayerLastName>
<SeatOrder>B</SeatOrder>
</Player>
<Player>
<MemberNumber></MemberNumber>
<MemberName></MemberName>
<PlayerFirstName></PlayerFirstName>
<PlayerLastName></PlayerLastName>
<SeatOrder>C</SeatOrder>
</Player>
</Players>
</Team>
</Teams>
</Tournament>")
我還建議更改您的類以使用 .NET 的標准命名約定。
Public Class TournamentTeam
Public Name As String
Public ID As Integer
Public ByeRounds As Integer
Public Status As Integer
Public Memo As String
Public PlayerA As PlayerInfo
Public PlayerB As PlayerInfo
Public PlayerC As PlayerInfo
End Class
Public Class PlayerInfo
Public MembershipName As String
Public MembershipNo As String
Public FirstName As String
Public LastName As String
Public SeatOrder As String
End Class
最后,我還要考慮刪除三個Player
屬性並放入一個字典。
如果始終是A
、 B
和C
,則使用 E Enum
作為鍵,否則使用String
。
Public Class TournamentTeam
Public Name As String
Public ID As Integer
Public ByeRounds As Integer
Public Status As Integer
Public Memo As String
Public Players As Dictionary(Of PlayerSeat, PlayerInfo)
End Class
Public Enum PlayerSeat
A
B
C
End Enum
Public Class PlayerInfo
Public MembershipName As String
Public MembershipNo As String
Public FirstName As String
Public LastName As String
Public SeatOrder As String
End Class
那么您的代碼將是:
Dim lstOutputTeams As List(Of TournamentTeam) = _
( _
From team In xd.Root.Element("Teams").Elements("Team") _
Select New TournamentTeam() With _
{
.ID = CInt(team.Element("TeamID")),
.Name = CStr(team.Element("TeamName")),
.Status = CInt(team.Element("Status")),
.Memo = CStr(team.Element("Memo")),
.ByeRounds = CInt(team.Element("ByeRounds")),
.Players = team.Element("Players").Elements("Player").Select(Function(player) _
New PlayerInfo() With _
{
.MembershipName = player.Element("MemberName").Value,
.MembershipNo = player.Element("MemberNumber").Value,
.FirstName = player.Element("PlayerFirstName").Value,
.LastName = player.Element("PlayerLastName").Value,
.SeatOrder = player.Element("SeatOrder").Value
}).ToDictionary(Function(x) CType([Enum].Parse(GetType(PlayerSeat), x.SeatOrder), PlayerSeat))
} _
).ToList()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.