簡體   English   中英

遍歷 XML

[英]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屬性並放入一個字典。

如果始終是ABC ,則使用 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM