Linq to XML如何在vb.net中执行此操作

时间:2010-01-28 12:25:42

标签: vb.net linq-to-xml

此代码段来自此answer

var reports = from report in xml.Descendants("report")
    where report.Element("name").Value.Contains("Adjustment Report")
    select new {
        Name = report.Element("name").Value,
        Extension = report.Element("extension").Value,
        FileType = report.Element("filetype").Value,
        Fields = report.Elements("field")
            .Select(f => new {
                Name = f.Attribute("name").Value, 
                Type = f.Attribute("type").Value 
            }).ToArray()
    };

对于我的生活,我无法在vb.net中弄清楚这部分的语法:

        Fields = report.Elements("field")
            .Select(**f =>** new {
                Name = f.Attribute("name").Value, 
                Type = f.Attribute("type").Value 
            }).ToArray()

我想要完成的事情 - 我的xml看起来像这样:

<items>
 <item>
  <id>data</id>
  <foto>
   <fotoname>img1.jpg</fotoname>
   <fotoorder>1</fotoorder>
  </foto>
  <foto>
   <fotoname>img2.jpg</fotoname>
   <fotoorder>2</fotoorder>
  </foto>
 </item>
</items>

我需要我的对象有一个foto元素的List(或任何类型的集合)。

3 个答案:

答案 0 :(得分:5)

LINQ to XML是VB.NET提供与C#完全不同的语法的领域之一。您可以使用相同的方法链接,但我更喜欢VB.NET LINQ语法,如下所示:

Sub Main()
    Dim myXml = <items>
                    <item>
                        <id>data</id>
                        <foto>
                            <fotoname>img1.jpg</fotoname>
                            <fotoorder>1</fotoorder>
                        </foto>
                        <foto>
                            <fotoname>img2.jpg</fotoname>
                            <fotoorder>2</fotoorder>
                        </foto>
                    </item>
                </items>

    Dim fotoElementsQuery = From f In myXml...<foto> _
                            Select f

    Dim fotoAnonymousTypeQuery = From f In myXml...<foto> _
                                 Select f.<fotoname>.Value, f.<fotoorder>.Value

    Dim fotoNamedTypeQuery = From f In myXml...<foto> _
                             Select New Foto With {.Name = f.<fotoname>.Value, .Order = f.<fotoorder>.Value}

End Sub

Public Class Foto

    Private _name As String
    Public Property Name() As String
        Get
            Return _name
        End Get
        Set(ByVal value As String)
            _name = value
        End Set
    End Property

    Private _order As Integer
    Public Property Order() As Integer
        Get
            Return _order
        End Get
        Set(ByVal value As Integer)
            _order = value
        End Set
    End Property

End Class

这为您提供了3种不同类型的IEnumerable结果。

  1. fotoElementsQuery的类型为IEnumerable(Of XElement)
  2. fotoAnonymousTypeQuery的类型为IEnumerable(Of <anonymous type>)。匿名类型的元素将采用xml元素的名称 - fotonamefotoorder
  3. fotoNamedTypeQuery的类型为IEnumeragle(Of Foto)
  4. LINQ查询尚未在上面的代码中实际执行。要获取List(并执行查询),请调用.ToList().ToArray()扩展方法。

    更新:在VB.NET中了解LINQ(以及LINQ to XML)的优点的最佳方法是观看Beth Massi的“如何使用视频系列”。 http://msdn.microsoft.com/en-us/vbasic/bb466226.aspx#linq

答案 1 :(得分:5)

充实其他一些答案:

在VB.NET中,您可以使用XML Axis运算符来简化方法语法。例如,<root>..<child>与XElement(“root”)相同.Elements(“child”)。在这种情况下,孩子必须直接在根下。如果要查找节点而不管子节点中存在哪些节点,您可以使用.Descendents代替.Elements,也可以使用带有三个点的VB语法,如下所示:<root>...<descendentNodeName>。如果您想访问某个属性,请按以下方式使用.@<root>.@attributeName

根据Murph的回复,您可以按如下方式在VB中重写它:

Fields = (From f In report.<field> _
          Select Name = f.@name, Type = f.@type).ToArray()

这也可以使用Lambda语法编写,如下所示:

Fields = report.<field> _
         .Select(Function(f) New With { _
             Name = f.@name, Type = f.@type).ToArray()

答案 2 :(得分:0)

Hah昨天读了这篇文章(如果我是对的 - 我可能不是所有语法的100%......)

Fields = report.Elements("field")
    .Select(Function(f) new { 
        Name = f.Attribute("name").Value,
        Type = f.Attribute("type").Value
    }).ToArray()

关键位 - 如果我的记忆力正常 - 正在改变“f =&gt;”到“功能(f)”