update multi-table dataset via datagridview vb

2019-09-06 20:53发布

问题:

Apologies - I know there's lots of info out there about this subject, but that's precisely the problem - so much info about this - hard to piece it all together to understand/get it working. So many concepts and approaches involved.

Basically have read an xml file into a Dataset. I want to be able to display the dataset in a datagridview, filterable by "controlleralias.alias" (tablename.field) and by "system.name" (names from the dataset visualizer). Then, any edits within the datagirdview are saved back into the dataset.

The XML file is in the following format:

<!-- 
    Configuration Remap file
-->
<mameconfig version="10">
    <!-- 
    ############################################################
    Define controller aliases, This just makes the controller names
    a little easier to deal with for the rest of the file.
    ############################################################
    -->
    <controlleralias>
        <id>Ultimarc Ultra-Stik Player 1</id>
        <alias>U360 Player1</alias>
    </controlleralias>
    <controlleralias>
        <id>WingMan Extreme Digital 3D</id>
        <alias>Flightstick</alias>
    </controlleralias>
    <controlleralias>
        <id>HID#VID_061C_PID_AA00#7_35df86d5_0_0000#</id>
        <alias>Lightgun1</alias>
    </controlleralias>

    <!-- 
    ############################################################
    This is the System Default section
    It generally should be the FIRST system section in the cfg file
    ############################################################
    -->
    <system name="default">
        <!-- put a controller element here to have it copied into ONLY this particular
         system element
    -->
        <controller id="U360 Player1">
            <input>
                <port type="P1_JOYSTICK_UP">
                    <newseq type="standard">JOYCODE_YAXIS_UP_SWITCH</newseq>
                </port>
                <port type="P1_JOYSTICK_DOWN">
                    <newseq type="standard">
                        JOYCODE_YAXIS_DOWN_SWITCH
                    </newseq>
                </port>
            </input>
        </controller>
        <controller id="Flightstick">
            <input>
                <port type="P1_SELECT">
                    <newseq type="standard">JOYCODE_BUTTON_7</newseq>
                </port>
                <port type="START1">
                    <newseq type="standard">JOYCODE_BUTTON8_SWITCH</newseq>
                </port>
            </input>
        </controller>
        <!-- this keyboard section provides a way to specify keyboard input
         mappings that should ALSO be made for the specific port types. -->
        <controller id="keyboard">
            <input>
                <port type="P1_JOYSTICK_UP">
                    <newseq type="standard">KEYCODE_UP</newseq>
                </port>
                <port type="P1_JOYSTICK_DOWN">
                    <newseq type="standard">KEYCODE_DOWN</newseq>
                </port>
                <port type="P1_JOYSTICK_LEFT">
                    <newseq type="standard">KEYCODE_LEFT</newseq>
                </port>
                <port type="P1_JOYSTICK_RIGHT">
                    <newseq type="standard">KEYCODE_RIGHT</newseq>
                </port>
            </input>
        </controller>

        <!-- 
        ###################################################
        ACTUAL INPUT MAPPING STARTS HERE
        DO NOT actually put anything in this section.
        It is completely cleared and regenerated!
        ###################################################
        -->
        <input></input>
    </system>


    <!-- 
    ###################################################
    This is a GAME specific section
    Add additional <controller> sections here
    to define how those controllers should map for this
    particular game
    ###################################################
    -->
    <system name="ribbit">
        <!-- This would be stupid to actually use, but as an example
         For this game ("Ribbit"), reverse the UP and DOWN directions
         on the joystick -->
        <controller id="U360 Player1">
            <input>
                <port type="P1_JOYSTICK_UP">
                    <newseq type="standard">
                        JOYCODE_YAXIS_DOWN_SWITCH
                    </newseq>
                </port>
                <port type="P1_JOYSTICK_DOWN">
                    <newseq type="standard">
                        JOYCODE_YAXIS_UP_SWITCH
                    </newseq>
                </port>
            </input>
        </controller>
        <!-- 
        ###################################################
        ACTUAL INPUT MAPPING STARTS HERE
        DO NOT actually put anything in this section.
        It is completely cleared and regenerated!
        ###################################################
        -->
        <input></input>
    </system>
</mameconfig>

Would appreciate any guidance as feel totally lost at the moment.

----- EDIT 1 and UPDATE ---------------

Getting closer with jd's help! As in comment post 2, the xml in and out: In:

<!-- 
    Configuration Remap file
-->
<mameconfig version="10">
    <!-- 
    ############################################################
    Define controller aliases, This just makes the controller names
    a little easier to deal with for the rest of the file.
    ############################################################
    -->
    <controlleralias>
        <id>HID#Vid_1241_Pid_1111#b_2eabd86_1_0000#</id>
        <alias>Trackball</alias>
    </controlleralias>
    <controlleralias>
        <id>Ultimarc Ultra-Stik Player 1</id>
        <alias>U360 Player1</alias>
    </controlleralias>
    <controlleralias>
        <id>WingMan Extreme Digital 3D</id>
        <alias>Flightstick</alias>
    </controlleralias>
    <controlleralias>
        <id>HID#VID_061C_PID_AA00#7_35df86d5_0_0000#</id>
        <alias>Lightgun1</alias>
    </controlleralias>

    <!-- 
    ############################################################
    This is the System Default section
    It generally should be the FIRST system section in the cfg file
    ############################################################
    -->
    <system name="default">
        <!-- put a controller element here to have it copied into ONLY this particular
         system element
    -->
        <controller id="U360 Player1">
            <input>
                <port type="P1_JOYSTICK_UP">
                    <newseq type="standard">JOYCODE_YAXIS_UP_SWITCH</newseq>
                </port>
                <port type="P1_JOYSTICK_DOWN">
                    <newseq type="standard">JOYCODE_YAXIS_DOWN_SWITCH</newseq>
                </port>
            </input>
        </controller>
        <controller id="Flightstick">
            <input>
                <port type="P1_SELECT">
                    <newseq type="standard">JOYCODE_BUTTON_7</newseq>
                </port>
                <port type="START1">
                    <newseq type="standard">JOYCODE_BUTTON8_SWITCH</newseq>
                </port>
            </input>
        </controller>
        <!-- this keyboard section provides a way to specify keyboard input
         mappings that should ALSO be made for the specific port types. -->
        <controller id="keyboard">
            <input>
                <port type="P1_JOYSTICK_UP">
                    <newseq type="standard">KEYCODE_UP</newseq>
                </port>
                <port type="P1_JOYSTICK_DOWN">
                    <newseq type="standard">KEYCODE_DOWN</newseq>
                </port>
                <port type="P1_JOYSTICK_LEFT">
                    <newseq type="standard">KEYCODE_LEFT</newseq>
                </port>
                <port type="P1_JOYSTICK_RIGHT">
                    <newseq type="standard">KEYCODE_RIGHT</newseq>
                </port>
            </input>
        </controller>
        <controller id="Trackball">
            <input>
                <port type="P1_TRACKBALL_X">
                    <newseq type="standard">MOUSECODE_XAXIS</newseq>
                </port>
                <port type="P1_TRACKBALL_Y">
                    <newseq type="standard">MOUSECODE_YAXIS</newseq>
                </port>
            </input>
        </controller>
        <controller id="Lightgun1">
            <input>
                <port type="P1_LIGHTGUN_X">
                    <newseq type="standard">GUNCODE_XAXIS</newseq>
                </port>
                <port type="P1_LIGHTGUN_Y">
            <newseq type="standard">GUNCODE_YAXIS</newseq>
                </port>
            </input>
        </controller>
        <!-- 
        ###################################################
        ACTUAL INPUT MAPPING STARTS HERE
        DO NOT actually put anything in this section.
        It is completely cleared and regenerated!
        ###################################################
        -->
        <input></input>
    </system>


    <!-- 
    ###################################################
    This is a GAME specific section
    Add additional <controller> sections here
    to define how those controllers should map for this
    particular game
    ###################################################
    -->
    <system name="ribbit">
        <!-- This would be stupid to actually use, but as an example
         For this game ("Ribbit"), reverse the UP and DOWN directions
         on the joystick -->
        <controller id="U360 Player1">
            <input>
                <port type="P1_JOYSTICK_UP">
                    <newseq type="standard">JOYCODE_YAXIS_DOWN_SWITCH</newseq>
                </port>
                <port type="P1_JOYSTICK_DOWN">
                    <newseq type="standard">JOYCODE_YAXIS_UP_SWITCH</newseq>
                </port>
            </input>
        </controller>
        <!-- 
        ###################################################
        ACTUAL INPUT MAPPING STARTS HERE
        DO NOT actually put anything in this section.
        It is completely cleared and regenerated!
        ###################################################
        -->
        <input></input>
    </system>
</mameconfig>

Out:

<?xml version="1.0" encoding="utf-8"?>
<mameconfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="10">
  <controlleralias>
    <id>Alias edit</id>
    <alias>HID#Vid_1241_Pid_1111#b_2eabd86_1_0000#</alias>
  </controlleralias>
  <controlleralias>
    <id>U360 Player1</id>
    <alias>HID#Vid_1241_Pid_1111#b_2eabd86_1_0000#</alias>
  </controlleralias>
  <controlleralias>
    <id>Flightstick</id>
    <alias>HID#Vid_1241_Pid_1111#b_2eabd86_1_0000#</alias>
  </controlleralias>
  <controlleralias>
    <id>keyboard</id>
    <alias>HID#Vid_1241_Pid_1111#b_2eabd86_1_0000#</alias>
  </controlleralias>
  <controlleralias>
    <id>Trackball</id>
    <alias>Ultimarc Ultra-Stik Player 1</alias>
  </controlleralias>
  <controlleralias>
    <id>Lightgun1</id>
    <alias>HID#Vid_1241_Pid_1111#b_2eabd86_1_0000#</alias>
  </controlleralias>
  <system name="default">
    <controller id="Alias edit">
      <input>
        <port type="Post edit">
          <newseq type="type edit">newseq edit</newseq>
        </port>
      </input>
    </controller>   
    <controller id="U360 Player1">
      <input>
        <port type="P1_JOYSTICK_DOWN">
          <newseq type="standard">JOYCODE_YAXIS_DOWN_SWITCH</newseq>
        </port>
      </input>
    </controller>
    <controller id="Flightstick">
      <input>
        <port type="P1_SELECT">
          <newseq type="standard">JOYCODE_BUTTON_7</newseq>
        </port>
        <port type="START1">
          <newseq type="standard">JOYCODE_BUTTON8_SWITCH</newseq>
        </port>
      </input>
    </controller>
    <controller id="keyboard">
      <input>
        <port type="P1_JOYSTICK_UP">
          <newseq type="standard">KEYCODE_UP</newseq>
        </port>
        <port type="P1_JOYSTICK_DOWN">
          <newseq type="standard">KEYCODE_DOWN</newseq>
        </port>
        <port type="P1_JOYSTICK_LEFT">
          <newseq type="standard">KEYCODE_LEFT</newseq>
        </port>
        <port type="P1_JOYSTICK_RIGHT">
          <newseq type="standard">KEYCODE_RIGHT</newseq>
        </port>
      </input>
    </controller>
    <controller id="Trackball">
      <input>
        <port type="P1_TRACKBALL_X">
          <newseq type="standard">MOUSECODE_XAXIS</newseq>
        </port>
        <port type="P1_TRACKBALL_Y">
          <newseq type="standard">MOUSECODE_YAXIS</newseq>
        </port>
      </input>
    </controller>
    <controller id="Lightgun1">
      <input>
        <port type="P1_LIGHTGUN_X">
          <newseq type="standard">GUNCODE_XAXIS</newseq>
        </port>
        <port type="P1_LIGHTGUN_Y">
          <newseq type="standard">GUNCODE_YAXIS</newseq>
        </port>
      </input>
    </controller>
  </system>
  <system name="ribbit">
    <controller id="U360 Player1">
      <input>
        <port type="P1_JOYSTICK_UP">
          <newseq type="standard">JOYCODE_YAXIS_DOWN_SWITCH</newseq>
        </port>
        <port type="P1_JOYSTICK_DOWN">
          <newseq type="standard">JOYCODE_YAXIS_UP_SWITCH</newseq>
        </port>
      </input>
    </controller>
  </system>
</mameconfig>

-------- EDIT 2 ------------

jd's script nearly there (thanks)! Just couple of probs left:

1) <controlleralias> element: Whilst writing the <id> and <alias> the right way round in <controlleralias>, it seems to be mapping the wrong <id>s against <alias>s in places. In:

<mameconfig version="10">
    <!-- 
    ############################################################
    Define controller aliases, This just makes the controller names
    a little easier to deal with for the rest of the file.
    ############################################################
    -->
    <controlleralias>
        <id>HID#Vid_1241_Pid_1111#b_2eabd86_1_0000#</id>
        <alias>Trackball</alias>
    </controlleralias>
    <controlleralias>
        <id>Ultimarc Ultra-Stik Player 1</id>
        <alias>U360 Player1</alias>
    </controlleralias>
    <controlleralias>
        <id>WingMan Extreme Digital 3D</id>
        <alias>Flightstick</alias>
    </controlleralias>
    <controlleralias>
        <id>HID#VID_061C_PID_AA00#7_35df86d5_0_0000#</id>
        <alias>Lightgun1</alias>
    </controlleralias>

    <!-- 
    ############################################################
    This is the System Default section
    It generally should be the FIRST system section in the cfg file
    ############################################################
    -->
    <system name="default">
        <!-- put a controller element here to have it copied into ONLY this particular
         system element
    -->
        <controller id="U360 Player1">
            <input>
                <port type="P1_JOYSTICK_UP">
                    <newseq type="standard">JOYCODE_YAXIS_UP_SWITCH</newseq>
                </port>
                <port type="P1_JOYSTICK_DOWN">
                    <newseq type="standard">JOYCODE_YAXIS_DOWN_SWITCH</newseq>
                </port>
            </input>
        </controller>

Out:

<?xml version="1.0" encoding="utf-8"?>
<mameconfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="10">
  <controlleralias>
    <id>HID#Vid_1241_Pid_1111#b_2eabd86_1_0000#</id>
    <alias>alias edit</alias>
  </controlleralias>
  <controlleralias>
    <id>HID#Vid_1241_Pid_1111#b_2eabd86_1_0000#</id>
    <alias>U360 Player1</alias>
  </controlleralias>
  <controlleralias>
    <id>HID#Vid_1241_Pid_1111#b_2eabd86_1_0000#</id>
    <alias>Flightstick</alias>
  </controlleralias>
  <controlleralias>
    <id>HID#Vid_1241_Pid_1111#b_2eabd86_1_0000#</id>
    <alias>keyboard</alias>
  </controlleralias>
  <controlleralias>
    <id>Ultimarc Ultra-Stik Player 1</id>
    <alias>Trackball</alias>
  </controlleralias>
  <controlleralias>
    <id>HID#Vid_1241_Pid_1111#b_2eabd86_1_0000#</id>
    <alias>Lightgun1</alias>
  </controlleralias>
  <system name="default">
    <controller id="alias edit">
      <input>
        <port type="port edit">
          <newseq type="type edit">desc edit</newseq>
        </port>
      </input>
    </controller>

2) It appears to be skipping the <input></input> (before any </system> tag) of the original (see Edit 1 full Out for example). I realize these are blank, but needed in the final output version too. Suppose could fix this by search and insert text file, but any way of fixing this?

----- EDIT 3 - Finishing touches -------------

jd cracked it! However, wanting to use this script to it's full potential.

I need to populate another datatable on the same form from a separate .xml file in this format:

<?xml version="1.0"?>
<!-- This file is autogenerated; comments and unknown tags will be stripped -->
<mameconfig version="10">
    <system name="default">
        <input>
            <port type="P1_START">
                <newseq type="standard">
                    KEYCODE_1 OR JOYCODE_1_BUTTON10
                </newseq>
            </port>
            <port type="P1_SELECT">
                <newseq type="standard">
                    JOYCODE_1_BUTTON9 OR KEYCODE_F4 OR JOYCODE_2_BUTTON9
                </newseq>
            </port>
        </input>
    </system>
</mameconfig>

I have tried this by altering the code, thus (commented outs left in):

 Dim xs2 As XmlSerializer = New XmlSerializer(GetType(Mameconfig))
        Dim reader2 As XmlTextReader = New XmlTextReader(My.Settings.CfgFile)
        mameconfig = CType(xs2.Deserialize(reader2), Mameconfig)
        reader2.Close()
        Version_textBox2.Text = mameconfig.version
        dt2 = New DataTable()
        dt2.Columns.Add("Name", GetType(String))
        'dt2.Columns.Add("Controller ID", GetType(String))
        'dt2.Columns.Add("Controller Alias", GetType(String))
        dt2.Columns.Add("Controller Port", GetType(String))
        dt2.Columns.Add("Type", GetType(String))
        dt2.Columns.Add("Description", GetType(String))
        For Each _system As c_System In mameconfig.system
            For Each port As Port In _system.input.port
                Dim newRow As DataRow = dt2.Rows.Add()
                newRow("Name") = _system.name
                'newRow("Controller Alias") = m_alias
                'newRow("Controller ID") = id
                newRow("Controller Port") = port.type
                newRow("Type") = port.newSeq._type
                newRow("Description") = port.newSeq.description
            Next
        Next

        MameCfgDGV.DataSource = dt2

However, getting some random functioning, either not loading, or loading with random values, I believe from the other xml/datatable. Is there a way to re-use the code to load other xml files into different data tables?

Apologies if not as per usual posting decorum - wasn't sure how to do "follow-up" questions..

回答1:

Here is vbnet

Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.Xml
Imports System.Xml.Serialization
Imports System.Xml.Schema
Imports System.IO
Public Class Form1
    Const FILENAME1 As String = "c:\temp\test.xml"
    Const FILENAME2 As String = "c:\temp\test2.xml"
    Dim mameconfig As Mameconfig = Nothing
    Dim dt As DataTable = Nothing

    Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.

        AddHandler Me.Load, AddressOf Form1_Load
    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs)

        Dim xs As XmlSerializer = New XmlSerializer(GetType(Mameconfig))
        Dim reader As XmlTextReader = New XmlTextReader(FILENAME1)
        mameconfig = CType(xs.Deserialize(reader), Mameconfig)

        reader.Close()

        Version_textBox.Text = mameconfig.version

        dt = New DataTable()
        dt.Columns.Add("Name", GetType(String))
        dt.Columns.Add("Controller ID", GetType(String))
        dt.Columns.Add("Controller Alias", GetType(String))
        dt.Columns.Add("Controller Port", GetType(String))
        dt.Columns.Add("Type", GetType(String))
        dt.Columns.Add("Description", GetType(String))



        For Each _system As c_System In mameconfig.system


            Dim m_alias As String = ""
            Dim id As String = ""
            For Each m_Controller As Controller In _system.controller

                Dim l_controller As Controller = m_Controller
                m_alias = m_Controller.id

                Dim controllerID = mameconfig.controlleralias.Where(Function(x) x._Alias = l_controller.id).FirstOrDefault()
                If Not controllerID Is Nothing Then

                    id = controllerID.id
                Else

                    id = ""
                End If
                For Each port As Port In m_Controller.input.port


                    Dim newRow As DataRow = dt.Rows.Add()
                    newRow("Name") = _system.name
                    newRow("Controller Alias") = m_alias
                    newRow("Controller ID") = id
                    newRow("Controller Port") = port.type
                    newRow("Type") = port.newSeq._type
                    newRow("Description") = port.newSeq.description
                Next
            Next
        Next
        DataGridView1.DataSource = dt
    End Sub



    Private Sub Write_Click(sender As System.Object, e As System.EventArgs) Handles Write.Click
        Dim mameconfig As New Mameconfig
        mameconfig.version = Version_textBox.Text
        Dim controllers = dt.AsEnumerable _
                          .GroupBy(Function(x) x.Field(Of String)("Controller Alias")) _
                          .ToDictionary(Function(x) x.Key, Function(y) y.First.Field(Of String)("Controller ID"))

        Dim controllerAlias As New List(Of Controlleralias)
        mameconfig.controlleralias = controllerAlias

        For Each key In controllers.Keys
            Dim newController As Controlleralias = New Controlleralias With { _
                ._Alias = key, .id = controllers(key) _
            }
            controllerAlias.Add(newController)
        Next key

        Dim m_Systems = dt.AsEnumerable() _
                                  .GroupBy(Function(x) x.Field(Of String)("Name"), Function(y) y) _
                                  .ToDictionary(Function(x) x.Key, Function(y) y.ToList())

        Dim c_Systems As New List(Of c_System)
        mameconfig.system = c_Systems
        For Each m_System_Key In m_Systems.Keys
            Dim newSystem As New c_System
            c_Systems.Add(newSystem)

            newSystem.input = New Input()

            newSystem.name = m_System_Key
            Dim IDs = m_Systems(m_System_Key).AsEnumerable() _
                       .GroupBy(Function(x) x.Field(Of String)("Controller Alias"), Function(y) y) _
                       .ToDictionary(Function(x) x.Key, Function(y) y.ToList())

            newSystem.controller = New List(Of Controller)
            For Each m_Controller_Keys In IDs.Keys
                Dim newController As New Controller
                newSystem.controller.Add(newController)

                newController.id = m_Controller_Keys
                Dim newInput As New Input
                newController.input = newInput
                Dim newPorts As New List(Of Port)
                newController.input.port = newPorts

                For Each m_Port In IDs(m_Controller_Keys)
                    Dim newPort As New Port
                    newPorts.Add(newPort)

                    newPort.type = m_Port.Field(Of String)("Controller Port")

                    newPort.newSeq = New NewSeq()

                    newPort.newSeq._type = m_Port.Field(Of String)("Type")
                    newPort.newSeq.description = m_Port.Field(Of String)("Description")

                Next m_Port

            Next m_Controller_Keys

        Next m_System_Key


        Dim serializer As XmlSerializer = New XmlSerializer(GetType(Mameconfig))

        Dim writer As StreamWriter = New StreamWriter(FILENAME2)
        serializer.Serialize(writer, mameconfig)
        writer.Flush()
        writer.Close()
        writer.Dispose()
    End Sub



End Class
<Serializable(), XmlRoot(ElementName:="mameconfig")>
Public Class Mameconfig
    Private m_version As String
    <XmlAttribute("version")>
    Public Property version() As String
        Get
            Return m_version
        End Get
        Set(ByVal value As String)
            m_version = value
        End Set
    End Property
    Private m_controlleralias As List(Of Controlleralias)
    <XmlElement("controlleralias")>
    Public Property controlleralias() As List(Of Controlleralias)
        Get
            Return m_controlleralias
        End Get
        Set(ByVal value As List(Of Controlleralias))
            m_controlleralias = value
        End Set
    End Property
    Private m_System As List(Of c_System)
    <XmlElement("system")>
    Public Property system() As List(Of c_System)
        Get
            Return m_System
        End Get
        Set(ByVal value As List(Of c_System))
            m_System = value
        End Set
    End Property

End Class
<Serializable(), XmlRoot(ElementName:="controlleralias")>
Public Class Controlleralias
    Private m_ID As String
    <XmlElement("id")>
    Public Property id() As String
        Get
            Return m_ID
        End Get
        Set(ByVal value As String)
            m_ID = value
        End Set
    End Property
    Private m_Alias As String
    <XmlElement("alias")>
    Public Property _Alias() As String
        Get
            Return m_Alias
        End Get
        Set(ByVal value As String)
            m_Alias = value
        End Set
    End Property
End Class
<Serializable(), XmlRoot(ElementName:="system")>
Public Class c_System
    Private m_Name As String
    <XmlAttribute("name")>
    Public Property name() As String
        Get
            Return m_Name
        End Get
        Set(ByVal value As String)
            m_Name = value
        End Set
    End Property
    Private m_Controller As List(Of Controller)
    <XmlElement("controller")>
    Public Property controller() As List(Of Controller)
        Get
            Return m_Controller
        End Get
        Set(ByVal value As List(Of Controller))
            m_Controller = value
        End Set
    End Property
    Private c_Input As Input
    <XmlElement("input")>
    Public Property input() As Input
        Get
            Return c_Input
        End Get
        Set(ByVal value As Input)
            c_Input = value
        End Set
    End Property
End Class
<Serializable(), XmlRoot(ElementName:="controller")>
Public Class Controller
    Private m_id As String
    <XmlAttribute("id")>
    Public Property id() As String
        Get
            Return m_id
        End Get
        Set(ByVal value As String)
            m_id = value
        End Set
    End Property
    Private c_Input As Input
    <XmlElement("input")>
    Public Property input() As Input
        Get
            Return c_Input
        End Get
        Set(ByVal value As Input)
            c_Input = value
        End Set
    End Property
End Class
<Serializable(), XmlRoot(ElementName:="input")>
Public Class Input
    Private c_port As List(Of Port)
    <XmlElement("port")>
    Public Property port() As List(Of Port)
        Get
            Return c_port
        End Get
        Set(ByVal value As List(Of Port))
            c_port = value
        End Set
    End Property
End Class
<Serializable(), XmlRoot(ElementName:="port")>
Public Class Port
    Private m_type As String
    <XmlAttribute("type")>
    Public Property type As String
        Get
            Return m_type
        End Get
        Set(ByVal value As String)
            m_type = value
        End Set
    End Property

    Private c_newSeq As NewSeq
    <XmlElement("newseq")>
    Public Property newSeq() As NewSeq
        Get
            Return c_newSeq
        End Get
        Set(ByVal value As NewSeq)
            c_newSeq = value
        End Set
    End Property


End Class
<Serializable(), XmlRoot(ElementName:="newseq")>
Public Class NewSeq
    Private m_description As String
    <XmlText()>
    Public Property description() As String
        Get
            Return m_description
        End Get
        Set(ByVal value As String)
            m_description = value
        End Set
    End Property
    Private m_type As String
    <XmlAttribute("type")>
    Public Property _type() As String
        Get
            Return m_type
        End Get
        Set(ByVal value As String)
            m_type = value
        End Set
    End Property
End Class


​


回答2:

Not usre if it is better to serialize or use DataSet. Both will work. I recommend binding the datagridview to either the serialize classes or the datatables. I didn't do the binding. Also recommend instead of editing in the datagridview use comboboxes or text boxes to do the editing. You can bind the boxes to the Dataset/classes

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace WindowsFormsApplication1
{

    public partial class Form1 : Form
    {
        const string FILENAME = @"c:\temp\test.xml";
        Mameconfig mameconfig = null;
        DataTable dt = null;
        public Form1()
        {
            InitializeComponent();
            this.Load += new EventHandler(Form1_Load);

        }
        private void Form1_Load(object sender, EventArgs e)
        {
            XmlSerializer xs = new XmlSerializer(typeof(Mameconfig));
            XmlTextReader reader = new XmlTextReader(FILENAME);
            mameconfig = (Mameconfig)xs.Deserialize(reader);

            reader.Close();

            Version_textBox.Text = mameconfig.version;

            DataTable dt = new DataTable();
            dt.Columns.Add("Name", typeof(string));
            dt.Columns.Add("Controller ID", typeof(string));
            dt.Columns.Add("Controller Alias", typeof(string));
            dt.Columns.Add("Controller Port", typeof(string));
            dt.Columns.Add("Type", typeof(string));
            dt.Columns.Add("Description", typeof(string));



            foreach (c_System _system in mameconfig.system)
            {

                string alias = "";
                string id = "";
                foreach (Controller controller in _system.controller)
                {
                    alias = controller.id;
                    var controllerID = mameconfig.controlleralias.Where(x => x.alias == controller.id).FirstOrDefault();
                    if (controllerID != null)
                    {
                        id = controllerID.id;
                    }
                    else
                    {
                        id = "";
                    }
                    foreach (Port port in controller.input.port)
                    {

                        DataRow newRow = dt.Rows.Add();
                        newRow["Name"] = _system.name;
                        newRow["Controller Alias"] = alias;
                        newRow["Controller ID"] = id;
                        newRow["Controller Port"] = port.type;
                        newRow["Type"] = port.newSeq.type;
                        newRow["Description"] = port.newSeq.description;
                    }

                }



            }
            dataGridView1.DataSource = dt;
        }

        private void Write_Click(object sender, EventArgs e)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Mameconfig));

            StreamWriter writer = new StreamWriter(FILENAME);
            serializer.Serialize(writer, mameconfig);
            writer.Flush();
            writer.Close();
            writer.Dispose();
        }
    }
    [XmlRoot("mameconfig")]
    public class Mameconfig
    {
        [XmlAttribute("version")]
        public string version { get; set; }
        [XmlElement("controlleralias")]
        public List<Controlleralias> controlleralias { get; set; }
        [XmlElement("system")]
        public List<c_System> system { get; set; }

    }
    [XmlRoot("controlleralias")]
    public class Controlleralias
    {
        [XmlElement("id")]
        public string id { get; set; }
        [XmlElement("alias")]
        public string alias { get; set; }
    }
    [XmlRoot("system")]
    public class c_System
    {
        [XmlAttribute("name")]
        public string name { get; set; }
        [XmlElement("controller")]
        public List<Controller> controller { get; set; }
    }
    [XmlRoot("controller")]
    public class Controller
    {
        [XmlAttribute("id")]
        public string id { get; set; }
        [XmlElement("input")]
        public Input input { get; set; }
    }
    [XmlRoot("input")]
    public class Input
    {
        [XmlElement("port")]
        public List<Port> port { get; set; }
    }
    [XmlRoot("port")]
    public class Port
    {
        [XmlAttribute("type")]
        public string type { get; set; }
        [XmlElement("newseq")]
        public NewSeq newSeq { get; set; }
    }
    public class NewSeq
    {
        [XmlText]
        public string description { get; set; }
        [XmlAttribute("type")]
        public string type { get; set; }
    }

}
​