Прошу помощи в парсенге XML в C#

Есть такой XML:

<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="PartUsage.XSL" ?>
<Report>
    <Infomation>
        <Title>Part usage</Title>
        <CreateDate>2020/06/16 00:58:54</CreateDate>
        <CreateUser>DefaultUser</CreateUser>
    </Infomation>
    <Search>
        <FromDate>2020/06/16 00:45:00</FromDate>
        <ToDate>2020/06/16 00:55:00</ToDate>
        <LineName></LineName>
        <MachineName></MachineName>
        <Recipes>
        </Recipes>
        <Option>0</Option>
        <ReportType>Type-A</ReportType>
    </Search>
    <Result>
        <Machines>
            <Machine>
                <Name>NXT1</Name>
                <Recipes>
                    <Recipe>
                        <Key>717</Key>
                        <Name>Recipe1</Name>
                        <StartTime>2020/06/16 00:45:00</StartTime>
                        <EndTime>2020/06/16 00:55:00</EndTime>
                        <Items>
                            <Item>
                                <PartName>PART1NXT1</PartName>
                                <Stage>0</Stage>
                                <GroupKey>0</GroupKey>
                                <Pos>0</Pos>
                                <SubPos>0</SubPos>
                                <Class></Class>
                                <PickupCount>0</PickupCount>
                                <TotalPartsUsed>0</TotalPartsUsed>
                                <RejectParts>0</RejectParts>
                                <PickupMiss>0</PickupMiss>
                                <ErrorParts>0</ErrorParts>
                                <DislodgedParts>0</DislodgedParts>
                                <DislodgedRate>0.000</DislodgedRate>
                                <RescanCount>0</RescanCount>
                                <LCRCheckUsed>0</LCRCheckUsed>
                                <PickupRate>0.000</PickupRate>
                                <RejectRate>0.000</RejectRate>
                                <ErrorRate>0.000</ErrorRate>
                                <SuccessRate>0.000</SuccessRate>
                                <UnitName>0</UnitName>
                                <FIDL></FIDL>
                            </Item>
                            <Item>
                                <PartName>PART2NXT1</PartName>
                                <Stage>0</Stage>
                                <GroupKey>0</GroupKey>
                                <Pos>0</Pos>
                                <SubPos>0</SubPos>
                                <Class></Class>
                                <PickupCount>0</PickupCount>
                                <TotalPartsUsed>0</TotalPartsUsed>
                                <RejectParts>0</RejectParts>
                                <PickupMiss>0</PickupMiss>
                                <ErrorParts>0</ErrorParts>
                                <DislodgedParts>0</DislodgedParts>
                                <DislodgedRate>0.000</DislodgedRate>
                                <RescanCount>0</RescanCount>
                                <LCRCheckUsed>0</LCRCheckUsed>
                                <PickupRate>0.000</PickupRate>
                                <RejectRate>0.000</RejectRate>
                                <ErrorRate>0.000</ErrorRate>
                                <SuccessRate>0.000</SuccessRate>
                                <UnitName>0</UnitName>
                                <FIDL></FIDL>
                            </Item>
                            <Item>
                                <PartName>PART3NXT1</PartName>
                                <Stage>0</Stage>
                                <GroupKey>0</GroupKey>
                                <Pos>0</Pos>
                                <SubPos>0</SubPos>
                                <Class></Class>
                                <PickupCount>0</PickupCount>
                                <TotalPartsUsed>0</TotalPartsUsed>
                                <RejectParts>0</RejectParts>
                                <PickupMiss>0</PickupMiss>
                                <ErrorParts>0</ErrorParts>
                                <DislodgedParts>0</DislodgedParts>
                                <DislodgedRate>0.000</DislodgedRate>
                                <RescanCount>0</RescanCount>
                                <LCRCheckUsed>0</LCRCheckUsed>
                                <PickupRate>0.000</PickupRate>
                                <RejectRate>0.000</RejectRate>
                                <ErrorRate>0.000</ErrorRate>
                                <SuccessRate>0.000</SuccessRate>
                                <UnitName>0</UnitName>
                                <FIDL></FIDL>
                            </Item>
                        </Items>
                    </Recipe>
                    <Recipe>
                        <Key>717</Key>
                        <Name>Recipe2</Name>
                        <StartTime>2020/06/16 00:45:00</StartTime>
                        <EndTime>2020/06/16 00:55:00</EndTime>
                        <Items>
                            <Item>
                                <PartName>PART1</PartName>
                                <Stage>0</Stage>
                                <GroupKey>0</GroupKey>
                                <Pos>0</Pos>
                                <SubPos>0</SubPos>
                                <Class></Class>
                                <PickupCount>0</PickupCount>
                                <TotalPartsUsed>0</TotalPartsUsed>
                                <RejectParts>0</RejectParts>
                                <PickupMiss>0</PickupMiss>
                                <ErrorParts>0</ErrorParts>
                                <DislodgedParts>0</DislodgedParts>
                                <DislodgedRate>0.000</DislodgedRate>
                                <RescanCount>0</RescanCount>
                                <LCRCheckUsed>0</LCRCheckUsed>
                                <PickupRate>0.000</PickupRate>
                                <RejectRate>0.000</RejectRate>
                                <ErrorRate>0.000</ErrorRate>
                                <SuccessRate>0.000</SuccessRate>
                                <UnitName>0</UnitName>
                                <FIDL></FIDL>
                            </Item>
                            <Item>
                                <PartName>PART2</PartName>
                                <Stage>0</Stage>
                                <GroupKey>0</GroupKey>
                                <Pos>0</Pos>
                                <SubPos>0</SubPos>
                                <Class></Class>
                                <PickupCount>0</PickupCount>
                                <TotalPartsUsed>0</TotalPartsUsed>
                                <RejectParts>0</RejectParts>
                                <PickupMiss>0</PickupMiss>
                                <ErrorParts>0</ErrorParts>
                                <DislodgedParts>0</DislodgedParts>
                                <DislodgedRate>0.000</DislodgedRate>
                                <RescanCount>0</RescanCount>
                                <LCRCheckUsed>0</LCRCheckUsed>
                                <PickupRate>0.000</PickupRate>
                                <RejectRate>0.000</RejectRate>
                                <ErrorRate>0.000</ErrorRate>
                                <SuccessRate>0.000</SuccessRate>
                                <UnitName>0</UnitName>
                                <FIDL></FIDL>
                            </Item>
                            <Item>
                                <PartName>PART3</PartName>
                                <Stage>0</Stage>
                                <GroupKey>0</GroupKey>
                                <Pos>0</Pos>
                                <SubPos>0</SubPos>
                                <Class></Class>
                                <PickupCount>0</PickupCount>
                                <TotalPartsUsed>0</TotalPartsUsed>
                                <RejectParts>0</RejectParts>
                                <PickupMiss>0</PickupMiss>
                                <ErrorParts>0</ErrorParts>
                                <DislodgedParts>0</DislodgedParts>
                                <DislodgedRate>0.000</DislodgedRate>
                                <RescanCount>0</RescanCount>
                                <LCRCheckUsed>0</LCRCheckUsed>
                                <PickupRate>0.000</PickupRate>
                                <RejectRate>0.000</RejectRate>
                                <ErrorRate>0.000</ErrorRate>
                                <SuccessRate>0.000</SuccessRate>
                                <UnitName>0</UnitName>
                                <FIDL></FIDL>
                            </Item>
                        </Items>
                    </Recipe>
                </Recipes>
            </Machine>
            <Machine>
                <Name>NXT2</Name>
                <Recipes>
                    <Recipe>
                        <Key>2125</Key>
                        <Name>Recipe2232</Name>
                        <StartTime>2020/06/16 00:45:00</StartTime>
                        <EndTime>2020/06/16 00:55:00</EndTime>
                        <Items>
                            <Item>
                                <PartName>Part112</PartName>
                                <Stage>0</Stage>
                                <GroupKey>0</GroupKey>
                                <Pos>0</Pos>
                                <SubPos>0</SubPos>
                                <Class></Class>
                                <PickupCount>0</PickupCount>
                                <TotalPartsUsed>0</TotalPartsUsed>
                                <RejectParts>0</RejectParts>
                                <PickupMiss>0</PickupMiss>
                                <ErrorParts>0</ErrorParts>
                                <DislodgedParts>0</DislodgedParts>
                                <DislodgedRate>0.000</DislodgedRate>
                                <RescanCount>0</RescanCount>
                                <LCRCheckUsed>0</LCRCheckUsed>
                                <PickupRate>0.000</PickupRate>
                                <RejectRate>0.000</RejectRate>
                                <ErrorRate>0.000</ErrorRate>
                                <SuccessRate>0.000</SuccessRate>
                                <UnitName>0</UnitName>
                                <FIDL></FIDL>
                            </Item>
                        </Items>
                    </Recipe>
                </Recipes>
            </Machine>
            <Machine>
                <Name>NXT3</Name>
                <Recipes>
                    <Recipe>
                        <Key>2884</Key>
                        <Name>Recipe12121</Name>
                        <StartTime>2020/06/16 00:45:00</StartTime>
                        <EndTime>2020/06/16 00:55:00</EndTime>
                        <Items>
                            <Item>
                                <PartName></PartName>
                                <Stage>0</Stage>
                                <GroupKey>0</GroupKey>
                                <Pos>0</Pos>
                                <SubPos>0</SubPos>
                                <Class></Class>
                                <PickupCount>0</PickupCount>
                                <TotalPartsUsed>0</TotalPartsUsed>
                                <RejectParts>0</RejectParts>
                                <PickupMiss>0</PickupMiss>
                                <ErrorParts>0</ErrorParts>
                                <DislodgedParts>0</DislodgedParts>
                                <DislodgedRate>0.000</DislodgedRate>
                                <RescanCount>0</RescanCount>
                                <LCRCheckUsed>0</LCRCheckUsed>
                                <PickupRate>0.000</PickupRate>
                                <RejectRate>0.000</RejectRate>
                                <ErrorRate>0.000</ErrorRate>
                                <SuccessRate>0.000</SuccessRate>
                                <UnitName>0</UnitName>
                                <FIDL></FIDL>
                            </Item>
                        </Items>
                    </Recipe>
                </Recipes>
            </Machine>
        </Machines>
    </Result>
</Report>

Мне нужно запарсить ветку Result для последующего переноса в DataGrid. Со зачениеми элементов Machine Name, Recipe Name, StartTime, EndTime, PartName, Stage и т.д.
Используя LinQ to XML, равно как и System.XML, не помогает мне добраться до вложенных элементов начиная с <item>, то есть я начинаю через foreach обходить все элементы начиная c уровня machine, но не получаю все PartName принадлежащие одному recipe и одной machine.

Код с которым я играюсь вот такой:

XDocument xdoc = XDocument.Load(@"C:\From\reports\history\DefaultUser\DefaultUser\PUS20200616004500000.XML");
foreach (XElement el in xdoc.Element("Report").Elements("Result").Elements("Machines").Elements("Machine"))
{               
    XElement NameElement = el.Element("Name");
    XElement ReciepeName = el.Element("Recipes").Element("Recipe").Element("Name");
    XElement StartTime = el.Element("Recipes").Element("Recipe").Element("StartTime");
    XElement EndTime = el.Element("Recipes").Element("Recipe").Element("EndTime");

    XElement PartName = el.Element("Recipes").Element("Recipe").Element("Items").Element("Item").Element("PartName");
   
    Console.WriteLine($"Name: {NameElement.Value}");
    Console.WriteLine($"RecipeName:{ReciepeName.Value}");
    Console.WriteLine($"StartTime:{StartTime.Value}");
    Console.WriteLine($"EndTime:{EndTime.Value}");
    Console.WriteLine($"PartName:{PartName.Value}");
}   
Console.ReadLine();

Выход вот такой:

Name: NXT1
RecipeName:Recipe1
StartTime:2020/06/16 00:45:00
EndTime:2020/06/16 00:55:00
PartName:PART1NXT1
Name: NXT2
RecipeName:Recipe2232
StartTime:2020/06/16 00:45:00
EndTime:2020/06/16 00:55:00
PartName:Part112
Name: NXT3
RecipeName:Recipe12121
StartTime:2020/06/16 00:45:00
EndTime:2020/06/16 00:55:00
PartName:Part108329329832

Направьте в нужную сторону.


Ответы (2 шт):

Автор решения: Alexander Petrov
var xdoc = XDocument.Load(...);

var machines = xdoc.Element("Report")
    .Elements("Result")
    .Elements("Machines")
    .Elements("Machine");

foreach (var machine in machines)
{
    var machineName = machine.Element("Name").Value;
    Console.WriteLine($"MachineName: {machineName}");

    foreach (var recipe in machine.Elements("Recipes").Elements("Recipe"))
    {
        var recipeName = recipe.Element("Name").Value;

        var startTime = (DateTime)recipe.Element("StartTime");
        var endTime = (DateTime)recipe.Element("EndTime");

        var partNames = recipe.Elements("Items")
            .Elements("Item")
            .Elements("PartName")
            .Select(x => x.Value);

        Console.WriteLine();
        Console.WriteLine($"RecipeName: {recipeName}");
        Console.WriteLine($"StartTime: {startTime}");
        Console.WriteLine($"EndTime: {endTime}");
        Console.WriteLine($"PartNames: {string.Join(", ", partNames)}");
    }

    Console.WriteLine();
}
→ Ссылка
Автор решения: Yitzhak Khabinsky

Вы можете попытаться достичь того, что вам нужно, используя LINQ to XML API.

Один цикл без осложнений.

c#

void Main()
{
    const string FILENAME = @"e:\temp\PUS20200616004500000.XML";

    XDocument doc = XDocument.Load(FILENAME);

    foreach (var el in doc.Descendants("Item"))
    {
        Console.WriteLine("Name: '{0}', RecipeName: '{1}', StartTime: '{2}', EndTime: '{3}', PartName: '{4}'"
            , el.Ancestors("Machine").Elements("Name").FirstOrDefault()?.Value
            , el.Ancestors("Recipe").Elements("Name").FirstOrDefault()?.Value
            , el.Ancestors("Recipe").Elements("StartTime").FirstOrDefault()?.Value
            , el.Ancestors("Recipe").Elements("EndTime").FirstOrDefault()?.Value
            , el.Element("PartName").Value);
    }
}

Вывод

Name: 'NXT1', RecipeName: 'Recipe1', StartTime: '2020/06/16 00:45:00', EndTime: '2020/06/16 00:55:00', PartName: 'PART1NXT1'
Name: 'NXT1', RecipeName: 'Recipe1', StartTime: '2020/06/16 00:45:00', EndTime: '2020/06/16 00:55:00', PartName: 'PART2NXT1'
Name: 'NXT1', RecipeName: 'Recipe1', StartTime: '2020/06/16 00:45:00', EndTime: '2020/06/16 00:55:00', PartName: 'PART3NXT1'
Name: 'NXT1', RecipeName: 'Recipe2', StartTime: '2020/06/16 00:45:00', EndTime: '2020/06/16 00:55:00', PartName: 'PART1'
Name: 'NXT1', RecipeName: 'Recipe2', StartTime: '2020/06/16 00:45:00', EndTime: '2020/06/16 00:55:00', PartName: 'PART2'
Name: 'NXT1', RecipeName: 'Recipe2', StartTime: '2020/06/16 00:45:00', EndTime: '2020/06/16 00:55:00', PartName: 'PART3'
Name: 'NXT2', RecipeName: 'Recipe2232', StartTime: '2020/06/16 00:45:00', EndTime: '2020/06/16 00:55:00', PartName: 'Part112'
Name: 'NXT3', RecipeName: 'Recipe12121', StartTime: '2020/06/16 00:45:00', EndTime: '2020/06/16 00:55:00', PartName: ''
→ Ссылка