LINQ to XML с подмножествами - PullRequest
0 голосов
/ 29 февраля 2012

У меня есть набор данных XML, который содержит несколько записей, и каждая запись может содержать от 1 до нескольких вложенных элементов с одинаковой группой идентификаторов (см. Элементы E04 в файле)

<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

Моя проблема в том, что этот код считывает каждое значение E04_01 из файла XML в массив с именем IncidentCrew. Если существует 200 записей, я получаю все записи E01_01 для всех 200 записей в каждом классе с именем IncidentCrew. Мне нужны только значения, связанные с одним 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 и не вижу, что не так или нет в моем коде.

1 Ответ

0 голосов
/ 02 марта 2012

Хорошо, довольно много, чтобы покрыть. Во-первых, ваш предметный тег для этого вопроса был "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 и найти ЛЮБЫХ потомков с именем, которое вы дали, которое существует ниже вызываемого узла. Вы вызываете это на узле записи, чтобы он нашел их все.

Я бы порекомендовал Отличный доклад Майка Таулти о LINQ to 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...