Прошу помощи в парсенге 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: ''