2012-02-28 24 views
0

我有一個包含多個記錄的XML數據集,並且每個記錄可以包含1到具有相同標識符組多個子元件(參照文件E04元素)LINQ爲XML的子集

<Record> 
<E01> 
<E01_01>9-542</E01_01> 
<E01_02>Ortivus</E01_02> 
<E01_03>Sweet-Billing &amp; 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文件到名爲IncidentCrew數組每E04_01值。如果有200條記錄,那麼我將獲得名爲IncidentCrew的每個類中的所有200條記錄的所有E01_01條目。我只想將與每個Record中唯一的一個PatientCareNumber E01_01相關聯的值讀入名爲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

好的,相當多的要覆蓋。首先你這個問題的主題標籤是「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建議Mike Taulty's excellent talk到XML

相反,你需要使用.Element()或.Elements(),它不僅外觀在第一級。我在這裏更正了代碼:

Sub Main() 
    Dim xml = <Record> 
        <E01> 
         <E01_01>9-542</E01_01> 
         <E01_02>Ortivus</E01_02> 
         <E01_03>Sweet-Billing &amp; 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