2016-11-12 103 views
-1

这是我的sample.xml文件。我正在寻找指导如何阅读此内容,并将所有节点(子节点)的内容放入DataSet中并将其显示在DataGrid中。我只能读取单个节点(没有子节点)。读取xml节点到数据集,编辑后代的值并保存(Visal Studio) - 重新打开

我的代码是下面:

Private Sub ReadXmlButton_Click() Handles ReadXmlButton.Click 

    Dim filePath As String = "C:\Path\" 
    DataSet.ReadXml("C:\Path\sample.xml") 

    DataGridView1.DataSource = DataSet 
    DataGridView1.DataMember = "CART_ID" 
End Sub 

但它没有子节点仅读取头节点(1000,10.05,YES,8,2)。我想从DataGridView中的第一个(也是全部)CART_ID中显示所有信息(例如:1000,10.05,A1A,Triangle,10,1,YES,8,2)。

我的结果: enter image description here

预期结果: enter image description here

sample.xml中

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
    <XML_FILE> 
     <typ>xml</typ> 
     <ID> 
      <NR>007</NR> 
     </ID> 
     <PERSONAL> 
      <Surname>John</Surname> 
      <Name>Smith</Name> 
     </PERSONAL> 
     <COUNTRY> 
      <CName>UK</CName> 
     </COUNTRY> 
      <CITY> 
      <TOWN> 
       <TOWN_ID> 
        <PART_ID> 
         <CART_ID> 
          <SIMPLE_ID>1000</SIMPLE_ID> 
          <SIMPLE_AREA_ID>10.05</SIMPLE_AREA_ID> 
          <PLACE_ID> 
           <SPECIFIC_ID> 
            <id>A1A</id> 
            <name>Triangle</name> 
            <area>10</area> 
            <note>1</note> 
           </SPECIFIC_ID> 
          </PLACE_ID> 
          <Control>YES</Control> 
          <Control_area>8</Control_area> 
          <Control_rest>2</Control_rest> 
         </CART_ID> 
           <CART_ID> 
          <SIMPLE_ID>2000</SIMPLE_ID> 
          <SIMPLE_AREA_ID>20.05</SIMPLE_AREA_ID> 
          <PLACE_ID> 
           <SPECIFIC_ID> 
            <id>B1B</id> 
            <name>Triangle</name> 
            <area>20</area> 
            <note>2</note> 
           </SPECIFIC_ID> 
          </PLACE_ID> 
          <Control>YES</Control> 
          <Control_area>18</Control_area> 
          <Control_rest>2</Control_rest> 
         </CART_ID> 
        </PART_ID> 
       </TOWN_ID> 
      </TOWN> 
     </CITY> 
</XML_FILE> 

更新: 最后一件事是如何将修改的后代(例如 - 手动将SIMPPLE_ID从1000更改为5000等)更改为原始sample.xml文件?用这个解决方案可以做到吗,还是应该寻找其他方法?

+0

您必须从每个“CART_ID”中创建所需字段的“拼合”类,将XML中的所有数据选择到该类的实例中,将每个实例添加到List(Of CartClass)并将该列表设置为网格数据源(无数据成员)。 – MrGadget

+0

@MrGadget如果你可以帮助我更多,我将不胜感激,我是一名编程初学者。 – Artec

+0

从学习[XmlDocument类](https://msdn.microsoft.com/en-us/library/system.xml.xmldocument(v = vs.110).aspx)和[List(Of T)Class ](https://msdn.microsoft.com/en-us/library/6sh2ey19(v = vs.110).aspx) – MrGadget

回答

0

@Artec我没有使用WinForms的时间最长,我不确定是否有更简单的方法来确定哪个特定的行和列已更改。就目前而言,我只是寻求最简单和最基本的解决方案,让您朝着正确的方向前进。

首先,我们不能直接将数据集替换回xml,因为您的xml结构。没有办法告诉代码需要深入到CART_ID元素的深层。所以,我们只是要颠倒加载xml的方法。

使用与我以前的答案相同的CartItem类,我们将DataGridView数据集转换为CartItem列表。使用列表的值更新xDoc元素并将xDocument保存回xml。

Public Class Form1 

    Private _CartItems As List(Of CartItem) 
    'TODO: Replace ... with the file location. 
    Private _FilePath As String = "...\source.xml" 

    '... Button1_Click and BuildCart in here. 

    Private Sub UpdateXmlButton_Click(sender As Object, e As EventArgs) Handles UpdateXmlButton.Click 
     _CartItems = DirectCast(DataGridView1.DataSource, List(Of CartItem)) 
     UpdateXml() 
     MessageBox.Show("Update Done.") 
    End Sub 

    Private Sub UpdateXml() 
     Dim xDoc As XDocument = XDocument.Load(_FilePath) 
     Dim cartIDs As IEnumerable(Of XElement) = xDoc.Root.Descendants("CART_ID") 

     For index As Integer = 0 To cartIDs.Count - 1 
      Dim cartElement As XElement = cartIDs.ElementAt(index) 
      Dim item As CartItem = _CartItems(index) 

      With cartElement 
       .Descendants("SIMPLE_ID").Value = item.Simple_Area_ID 
       .Descendants("SIMPLE_AREA_ID").Value = item.Simple_ID 
       .Descendants("id").Value = item.Place_ID 
       .Descendants("name").Value = item.Place_Name 
       '... 
      End With 
     Next 

     xDoc.Save(_FilePath) 
    End Sub 
End Class 

你几乎改变加载的XDocument的元素在内存中把它丢在回XML文件。肯定有很多可以完成的改进,例如:

  • 循环浏览属性,而不是对行中的每个属性进行编码。这可以通过反射和字典的结合来实现。
  • 已更改,而不是改变整个事情

但上面的代码应该让你开始仅更新的元素。

+0

Ricardo就是这样!谢谢你的改进和你的帮助。现在我可以尝试开始构建下一个模块。 – Artec

1

@Artec假设3两件事:

您的购物车节点的
  • 结构是标准
  • 你知道
  • 你使用Windows窗体,因为你有DataGridView控件的节点的名称

...不是使用数据集,而是首先创建一个类,其属性对应于您需要的数据的节点

Public Class CartItem 

    Public Property Simple_ID As String 
    Public Property Simple_Area_ID As String 
    Public Property Place_ID As String 
    Public Property Place_Name As String 
    '... 

End Class 

现在在您的Form类上,通过XDocument从xml文件中获取数据并创建一个CartItem列表。

Public Class Form1 

    Private _CartItems As List(Of CartItem) 

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
     _CartItems = New List(Of CartItem) 

     'TODO: Replace ... below with your file location. 
     BuildCart("...\sample.xml") 
     DataGridView1.DataSource = _CartItems 
    End Sub 

    Private Sub BuildCart(XmlSourcePath As String) 
     Dim xDoc As XDocument = XDocument.Load(XmlSourcePath) 
     For Each cartElement As XElement In xDoc.Root.Descendants("CART_ID") 
      Dim item As New CartItem 

      With cartElement 
       item.Simple_Area_ID = .Descendants("SIMPLE_ID").Value 
       item.Simple_ID = .Descendants("SIMPLE_AREA_ID").Value 
       item.Place_ID = .Descendants("id").Value 
       item.Place_Name = .Descendants("name").Value 
       '... 
      End With 

      _CartItems.Add(item) 
     Next 
    End Sub 
End Class 

注意:有几种方法可以读取xml文件,如XMLTextReader;的XMLDocument; XPathDocument中; XMLReader的;等等。这只是我个人的喜好,去与XDocument。如果你想查看其他选项,你将不得不做一些研究。这一切都取决于您的XML文件的复杂性,您的要求和偏好。

这应该让你走向正确的方向。

+0

非常感谢!这正是我所期待的。我知道这不是我的问题,但如何手动保存源xml文件的更改。我的代码'Dim filename As String =“... \ sample_out.xml”''DataSet.WriteXml(filename)'不保存数据以读取文件。 – Artec

+0

@Artec很高兴我能帮到你。关于你的后续问题,我认为它太模糊,需要更多的细节: –

+0

@Artec oops,按下输入太快。 所以细节如:你是否添加Cart_ID的新元素?你是否在改变现有Card_ID的后代之一的价值? 另外,我认为值得另一个问题。与原来的问题相比,这个问题相对来说不是问题。 –