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

Vnu*_*nuk 3 vb.net linq-to-xml

这个片段来自这个答案

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()
    };
Run Code Online (Sandbox Code Playgroud)

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

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

我想要完成的任务 - 我的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>
Run Code Online (Sandbox Code Playgroud)

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

Cod*_*nis 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
Run Code Online (Sandbox Code Playgroud)

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

  1. fotoElementsQuery 将是类型 IEnumerable(Of XElement)
  2. fotoAnonymousTypeQuery将是类型IEnumerable(Of <anonymous type>).匿名类型的元素将采用xml元素的名称 - fotonamefotoorder.
  3. fotoNamedTypeQuery 将是类型 IEnumeragle(Of Foto)

LINQ查询尚未在上面的代码中实际执行.为了获取List(并执行查询),请调用.ToList().ToArray()扩展方法.

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


Jim*_*ley 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()
Run Code Online (Sandbox Code Playgroud)

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

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