我是一个LINQ新手,我遇到了以下问题。我正在尝试使用XML文件上的LINQ执行查询,并将结果存储在与XML匹配的DataClass对象列表中。
我有一个XML文件,定义如下:
<NewDataSet>
<NewDataTable>
<Field>Accepted ASNs</Field>
<Val>59</Val>
<Order Number="1234" ShipDate="2009/05/21" />
<Order Number="2190" ShipDate="2009/05/22" />
<Order Number="1809" ShipDate="2009/05/22" />
</NewDataTable>
<NewDataTable>
<Field>Rejected ASNs</Field>
<Val>8</Val>
<Order Number="2901" ShipDate="2009/05/21" />
<Order Number="2810" ShipDate="2009/05/24" />
<Order Number="1419" ShipDate="2009/05/25" />
</NewDataTable>
<NewDataTable>
<Field>Missing ASNs</Field>
<Val>7</Val>
<Order Number="2902" ShipDate="2009/05/19" />
<Order Number="2898" ShipDate="2009/05/20" />
<Order Number="1296" ShipDate="2009/05/22" />
</NewDataTable>
</NewDataSet>
我创建了一个Data类来支持这种XML格式。我想要做的是创建一个LINQ查询来获取这3条记录并将它们存储到我的DataClass列表中。
为了支持多个Order元素,我的类定义了一个“Order”结构的通用列表......它看起来像这样:
Public Class ASNData
Private _field As String
Private _value As String
Private _orders As List(Of Order)
Public Property Field() As String
Get
Set
End Property
Public Property Value() As String
Get
Set
End Property
Public Property Orders() As List(Of Order)
Get
Set
End Property
Structure Order
Private _number As String
Private _date As Date
Public Property Number() As String
Get
Set
End Property
Public Property ShippingDate() As Date
Get
Set
End Property
End Structure
End Class
我遇到的最大问题是弄清楚如何获取3阶元素并将它们存储到我的Order结构列表中。
有人能指出我正确的方向吗?
谢谢。
答案 0 :(得分:4)
以下是您需要LINQ查询的Console应用程序的代码。我必须填写你的类的getter和setter并包含结构,但这是经过测试的工作代码。要获取List(Of ASNData),只需调用DataTables.ToList
当然,这适用于任意数量的Order元素。
使用Structure Order工作得很好。我会使用一个类,但不需要为了这个而改变它。
此代码的关键部分是LINQ查询:
Dim DataTables = From NewDataTable In TestData...<NewDataTable> _
Select New ASNData With {.Field = NewDataTable.<Field>.Value, _
.Value = NewDataTable.<Val>.Value, _
.Orders = (From AnOrder In NewDataTable...<Order> _
Select New ASNData.Order With _
{.Number = AnOrder.@Number, _
.ShippingDate = Date.Parse(AnOrder.@ShipDate)}).ToList}
以下是完整的工作控制台应用程序:
Module Module1
Sub Main()
Dim TestData = <NewDataSet>
<NewDataTable>
<Field>Accepted ASNs</Field>
<Val>59</Val>
<Order Number="1234" ShipDate="2009/05/21"/>
<Order Number="2190" ShipDate="2009/05/22"/>
<Order Number="1809" ShipDate="2009/05/22"/>
</NewDataTable>
<NewDataTable>
<Field>Rejected ASNs</Field>
<Val>8</Val>
<Order Number="2901" ShipDate="2009/05/21"/>
<Order Number="2810" ShipDate="2009/05/24"/>
<Order Number="1419" ShipDate="2009/05/25"/>
</NewDataTable>
<NewDataTable>
<Field>Missing ASNs</Field>
<Val>7</Val>
<Order Number="2902" ShipDate="2009/05/19"/>
<Order Number="2898" ShipDate="2009/05/20"/>
<Order Number="1296" ShipDate="2009/05/22"/>
</NewDataTable>
</NewDataSet>
Dim DataTables = From NewDataTable In TestData...<NewDataTable> _
Select New ASNData With {.Field = NewDataTable.<Field>.Value, .Value = NewDataTable.<Val>.Value, _
.Orders = (From AnOrder In NewDataTable...<Order> _
Select New ASNData.Order With {.Number = AnOrder.@Number, .ShippingDate = Date.Parse(AnOrder.@ShipDate)}).ToList}
Console.WriteLine(DataTables.Count)
Console.ReadLine()
End Sub
Public Class ASNData
Private _field As String
Private _value As String
Private _orders As List(Of Order)
Public Property Field()
Get
Return _field
End Get
Set(ByVal value)
_field = value
End Set
End Property
Public Property Value() As String
Get
Return _value
End Get
Set(ByVal value As String)
_value = value
End Set
End Property
Public Property Orders() As List(Of Order)
Get
Return _orders
End Get
Set(ByVal value As List(Of Order))
_orders = value
End Set
End Property
Structure Order
Private _number As String
Private _date As Date
Public Property Number() As String
Get
Return _number
End Get
Set(ByVal value As String)
_number = value
End Set
End Property
Public Property ShippingDate() As Date
Get
Return _date
End Get
Set(ByVal value As Date)
_date = value
End Set
End Property
End Structure
End Class
End Module
答案 1 :(得分:0)
要获取订单元素(来自NewDataTable
元素),您需要使用
newDataTableElement.Elements("Order")
将返回IEnumerable<XElement>
- 您可以使用Select
正常转换每个 element.Attribute("Number").Value
element.Attribute("ShipDate").Value
。要获取属性,请使用:
XAttribute
这会将值用作字符串 - 您可以 CType(element.Attribute("Number"), Integer)
CType(element.Attribute("ShipDate"), DateTime)
为您进行转换:
DateTime.ParseExact
我不是100%认为这对你的约会有用,因为它可能会有一个完整的日期和时间 - 值得一试。否则,只需使用Order
解析字符串。
我强烈建议您重新考虑{{1}}作为结构 - 尤其是可变结构。是什么原因使它成为一个结构而不是一个类?
答案 2 :(得分:0)
XDocument xmlDoc = XDocument.Load(Server.MapPath("Order.xml"));
List<ASNData> lst= (from data in xmlDoc.Root.Elements("NewDataTable")
select new ASNData
{
Field=data.Element("Field").Value,
Value=data.Element("Val").Value,
Orders=(from ord in data.Elements("Order")
select new Order
{
Number=ord.Attribute("Number").Value,
ShippingDate=Convert.ToDateTime(ord.Attribute("ShipDate").Value)
}).ToList<Order>()
}).ToList<ASNData>();
foreach(ASNData a in lst)
{
Response.Write("Field:"+a.Field+"</br>");
Response.Write("Value:"+a.Value+"</br>");
Response.Write("Orders:"+"</br>");
foreach(Order o in a.Orders)
{
Response.Write("OrderNum:"+o.Number+"</br>");
Response.Write("ShipDate:"+o.ShippingDate+"</br>");
}
}
答案 3 :(得分:-1)
var result = from order in YourXMLVar.Descendants("NewDataTable")
.First().Elements("Order") select order;
这应该会给你一个订单数组。
然后你应该可以做类似的事情:
foreach(var order in result)
{
int someVal = Convert.ToInt32(order.Attribute("Number").Value);
}
//编辑:显然,你不会使用First(),而是会遍历你的命令或你的逻辑指令。我使用了First(),因为它是一个简单的演示。