【问题标题】:Use LINQ to query XML into an array using .ToArray()使用 LINQ 将 XML 查询到使用 .ToArray() 的数组中
【发布时间】:2014-12-05 22:12:52
【问题描述】:

我是一名 VB6 资深人士,逐渐掌握了 VB.NET。我有一个正在尝试使用 XML 文件配置的工作应用程序(基本应用程序设置除外)。

我想从文件中的单个 XML 节点读取元素并创建一个字符串数组。我搜索了这个站点和其他站点,发现了许多执行非常相似的操作的示例,但不能完全掌握它(特别是如果问题/答案是用 C# 编写的)。

我不是 XML 专家,但我知道如何选择单个节点,并且我可以编写一些相当简洁的代码,这些代码将遍历子元素并使用 redim 手动构建数组,这样可以正常工作。但是...我正在尝试通过具体示例来学习新技术。

所以...看来,我应该能够编写一个 LINQ 查询并使用 .ToArray() 扩展方法来填充数组,而无需使用循环构造。

p>

这是我的 XML 的表示:

<?xml version="1.0"?>
<targets>
  <target name="abc">
    <index>0</index>
    <randoms>
      <string>index</string>
      <string>local</string>
      <string>news</string>
      <string>journal</string>
      <string>information</string>
    </randoms>
  </target>
  <target name="xyz">
    <index>1</index>
    <randoms>
      <string>cat</string>
      <string>dog</string>
      <string>mouse</string>
    </randoms>
  </target>
</targets>

我想要构建数组的元素是“字符串”元素。在我的代码中,我将使用目标索引来选择适当的节点(会有“随机”以外的节点,但它们与本示例无关。

【问题讨论】:

  • 顺便说一句,我也从 VB6 迁移到 VB.Net,但那是几年前的事了。您应该尽可能多地采用 .NET 类。序列化可以使这种事情变得更容易。会有解析或迭代XML的解决方案,但我相信这种方法更清晰,更面向对象。
  • 我很欣赏 cmets @Verdolino(很快就会强调使用序列化),但您的回答并未证明 LINQ 和 .ToArray() 扩展方法的使用。
  • 考虑第一个示例,如果您已序列化到 XmlModel 类,则不需要使用 ToArray()。该类有一个List(Of XmlMob),它是 IEnumerable。

标签: arrays vb.net linq-to-xml


【解决方案1】:

此解决方案创建一个对象,将其保存到 xml 文件中,将其设置为空,然后从 xml 文件中加载回来。制作一个新的控制台应用程序并用您在下面看到的内容覆盖所有代码。

奖励:ToArray() 用于证明该类的列表成员是 IEnumerable

Imports System.Xml.Serialization
Imports System.IO

Module Module1

    Private targets As XmlTargets

    Sub Main()
        targets = New XmlTargets
        targets.Targets = New List(Of XmlTarget)

        Dim t1 As New XmlTarget
        t1.Name = "abc"
        t1.Index = 0
        t1.Randoms = New Random()
        t1.Randoms.Strings = New List(Of [String])
        Dim s1 As New [String]()
        s1.Type = 1
        s1.Text = "index"
        Dim s2 As New [String]()
        s2.Type = 2
        s2.Text = "value"
        t1.Randoms.Strings.Add(s1)
        t1.Randoms.Strings.Add(s2)


        Dim t2 As New XmlTarget
        t2.Name = "xyz"
        t2.Index = 1
        t2.Randoms = New Random()
        t2.Randoms.Strings = New List(Of [String])

        targets.Targets.Add(t1)
        targets.Targets.Add(t2)
        SaveXmlFile()
        targets = Nothing
        LoadXmlFile()
        Dim ts = targets.Targets.ToArray()
    End Sub

    Private Sub LoadXmlFile()
        Dim s As New XmlSerializer(GetType(XmlTargets))
        Using sr As New StreamReader("test.xml")
            targets = s.Deserialize(sr)
        End Using
    End Sub

    Private Sub SaveXmlFile()
        Dim s As New XmlSerializer(GetType(XmlTargets))

        Using sw As New StreamWriter("test.xml")
            s.Serialize(sw, targets)
        End Using
    End Sub

End Module

<XmlRoot("targets")>
Public Class XmlTargets
    <XmlElement("target")>
    Public Property Targets As List(Of XmlTarget)
End Class

<Serializable>
Public Class XmlTarget
    <XmlAttribute("name")>
    Public Property Name As String
    <XmlElement("index")>
    Public Property Index As Integer
    <XmlElement("randoms")>
    Public Property Randoms As Random
End Class

<Serializable>
Public Class Random
    <XmlElement("string")>
    Public Property Strings As List(Of [String])
End Class

<Serializable>
Public Class [String]
    <XmlAttribute("type")>
    Public Property [Type] As Integer
    <XmlText>
    Public Property Text As String
End Class

这是软件创建的 XML 文件。注意:我没有在上面的代码之外编辑这个文件——它是通过序列化类创建的。

<?xml version="1.0" encoding="utf-8"?>
<targets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <target name="abc">
    <index>0</index>
    <randoms>
      <string type="1">index</string>
      <string type="2">value</string>
    </randoms>
  </target>
  <target name="xyz">
    <index>1</index>
    <randoms />
  </target>
</targets>

帖子已被编辑以反映下面评论中要求的更改。

【讨论】:

  • 感谢您花时间充实示例。我现在可以看到序列化将是多么简单和有用,而您并没有给我我认为我想要的答案,而是我可能需要的答案。
  • 我已经按照建议实现了反序列化(在这种特殊情况下我没有使用序列化)并且它按预期工作。我现在的问题是,如果我向字符串元素添加一个属性(即 'index' 我似乎无法做到这一点。我已经用谷歌搜索并通读了关于堆栈溢出,直到我睁一只眼闭一只眼!
  • 你需要另一个课程。当我到达我的办公桌时,我可以添加它
  • 请看我的编辑。您的 xml &lt;string type="1"&gt;index&lt;/string&gt; 将使用 &lt;XmlText&gt; 属性。我已经改变了这个类。
  • 如果没有那一行,不清楚最后一行中的targets.Targets.ToArray() 是否与序列化/反序列化之前的原始数据相比发生了变化。也许代码可以更清晰,但这只是一个演示。
猜你喜欢
  • 2017-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-31
  • 1970-01-01
相关资源
最近更新 更多