我有一个包含多个记录的XML数据集,每个记录可以包含1到多个具有相同标识符组的子元素(参见文件中的E04元素)
<Record>
<E01>
<E01_01>9-542</E01_01>
<E01_02>Ortivus</E01_02>
<E01_03>Sweet-Billing & Field Data</E01_03>
<E01_04>5.6.020120130</E01_04>
</E01>
<E02>
<E02_01>123</E02_01>
<E02_02>-20</E02_02>
<E02_03>F12006149</E02_03>
<E02_04>30</E02_04>
<E02_05>75</E02_05>
<E02_06>105</E02_06>
<E02_07>150</E02_07>
<E02_08>225</E02_08>
<E02_09>290</E02_09>
<E02_10>360</E02_10>
<E02_11>-20</E02_11>
<E02_12>447</E02_12>
<E02_13>-20</E02_13>
<E02_14>-20</E02_14>
<E02_17>2.3</E02_17>
<E02_18>3</E02_18>
<E02_19>3.7</E02_19>
</E02>
<E03>
<E03_01>445</E03_01>
<E03_02>-20</E03_02>
<E03_03>-25</E03_03>
</E03>
<E04>
<E04_01>155306</E04_01>
<E04_02>580</E04_02>
<E04_03>6120</E04_03>
</E04>
<E04>
<E04_01>032519</E04_01>
<E04_02>585</E04_02>
<E04_03>6090</E04_03>
</E04>
<E04>
<E04_01>083589</E04_01>
<E04_02>590</E04_02>
<E04_03>6090</E04_03>
</E04>
</Record>
我的提取VB.NET代码是这样的(查找下面的IncidentCrew)
Dim ns As XNamespace = doc.Root.Name.[Namespace] Tripsheets = _
(From record In doc.Descendants(ns + "Record") _
Select New TripSheet() With _
{ _
.PatientCareNumber = record.Descendants(ns + "E01_01").FirstOrDefault, _
.IncidentCrew = (From E0401 In doc.Descendants(ns + "E04") _
Select New Crew() With _
{ _
.CrewID = cr.Descendants(ns + "E04_01").FirstOrDefault _
}).ToArray, _
.MileageOut = record.Descendants(ns + "E02_16").FirstOrDefault, _
.MileageAtScene = record.Descendants(ns + "E02_17").FirstOrDefault, _
.MileageAtDestination = record.Descendants(ns+"E02_18").FirstOrDefault, _
.MileageInQuarters = record.Descendants(ns + "E02_19").FirstOrDefault, _
}).ToList
我的问题是这段代码将XML文件中的每个E04_01值读入名为IncidentCrew的数组中。如果有200条记录,那么我会在名为IncidentCrew的每个类中获得所有200条记录的所有E01_01条目。我只希望与一个PatientCareNumber E01_01相关联的值在每个Record中唯一读入名为IncidentCrew的类中,该类被定义为TripSheet类的一部分。课程如下所示
Public Class TripSheet
Public PatientCareNumber As String
Public TimeDispatched As String
Public TimeEnroute As String
Public TimeAtScene As String
Public TimeDepartScene As String
Public TimeArriveFacility As String
Public TimeAvailable As String
Public TimeInQuarters As String
Public MileageOut As String
Public MileageAtScene As String
Public MileageAtDestination As String
Public MileageInQuarters As String
Public IncidentCrew As Crew()
End Class
Public Class Crew
Public CrewID As String
End Class
有人可以帮助我吗?我是LINQ的新手,我无法看到代码中出现的错误或缺失。
答案 0 :(得分:0)
好的,还有很多东西需要报道。首先,这个问题的主题标签是“Linq-to-sql”,而不是“linq-to-xml”所以我已经纠正了这一点。
第二个问题 - 您控制的XML格式是什么?如果是这样,那么您可能需要考虑重写它,以便数据的结构与您的类的结构相匹配。这意味着您可以将XML直接序列化到您的类中。它使阅读更容易。例如,如果它看起来像这样,那么你的XML可能更具可读性:
Dim better = <TripSheet>
<PatientCareNumber>9-542</PatientCareNumber>
<!-- other fields -->
<MileageOut>123</MileageOut>
<MileageAtScene>321</MileageAtScene>
<MileageAtDestination>456</MileageAtDestination>
<IncidentCrew>
<Crew CrewID="1234"/>
<Crew CrewID="5678"/>
<Crew CrewID="9876"/>
</IncidentCrew>
</TripSheet>
我会假设这种格式已经强加给你,你无法改变它。在这种情况下,这里的关键问题是.Descendants() - 这告诉LINQ to XML向下移动所有XML节点并找到任何后代,其中包含您在调用的节点下面存在的名称。您可以在Record节点上调用它,以便全部找到它们。
我建议在LINQ to XML上使用Mike Taulty's excellent talk
相反,您需要使用仅查看第一级的.Element()或.Elements()。我在这里更正了代码:
Sub Main()
Dim xml = <Record>
<E01>
<E01_01>9-542</E01_01>
<E01_02>Ortivus</E01_02>
<E01_03>Sweet-Billing & Field Data</E01_03>
<E01_04>5.6.020120130</E01_04>
</E01>
<E02>
<E02_01>123</E02_01>
<E02_02>-20</E02_02>
<E02_03>F12006149</E02_03>
<E02_04>30</E02_04>
<E02_05>75</E02_05>
<E02_06>105</E02_06>
<E02_07>150</E02_07>
<E02_08>225</E02_08>
<E02_09>290</E02_09>
<E02_10>360</E02_10>
<E02_11>-20</E02_11>
<E02_12>447</E02_12>
<E02_13>-20</E02_13>
<E02_14>-20</E02_14>
<E02_17>2.3</E02_17>
<E02_18>3</E02_18>
<E02_19>3.7</E02_19>
</E02>
<E03>
<E03_01>445</E03_01>
<E03_02>-20</E03_02>
<E03_03>-25</E03_03>
</E03>
<E04>
<E04_01>155306</E04_01>
<E04_02>580</E04_02>
<E04_03>6120</E04_03>
</E04>
<E04>
<E04_01>032519</E04_01>
<E04_02>585</E04_02>
<E04_03>6090</E04_03>
</E04>
<E04>
<E04_01>083589</E04_01>
<E04_02>590</E04_02>
<E04_03>6090</E04_03>
</E04>
</Record>
Dim doc As New XDocument(xml)
'Dim ns As XNamespace = doc.Root.Name.[Namespace]
'get each record
Dim TripSheets = (From record In doc.Elements("Record") _
Let e01 = record.Element("E01") _
Let e02 = record.Element("E02") _
Let e04s = record.Elements("E04") _
Select New TripSheet With _
{ _
.PatientCareNumber = e01.Element("E01_01"), _
.IncidentCrew = (From e04 In e04s _
Select New Crew() With {.CrewID = e04.Element("E04_01")}).ToArray(), _
.MileageOut = e02.Element("E02_16"), _
.MileageAtScene = e02.Element("E02_17"), _
.MileageAtDestination = e02.Element("E02_18"), _
.MileageInQuarters = e02.Element("E02_19") _
}).ToList()
For Each trip In TripSheets
Console.WriteLine("{0} -> {1} crew", trip.PatientCareNumber, trip.IncidentCrew.Count)
Next
Console.ReadKey()
End Sub
End Module