Мое решение - я решил создать класс Label
для сопоставления 1 отдельной метки и класс LabelGroup
для сопоставления всех меток определенного элемента <instance>
:
public class Label
{
public string Group { get; set; }
public string Text { get; set; }
public override string ToString()
{
if (string.IsNullOrEmpty(Group))
{
return Text ?? string.Empty;
}
return $"{Group ?? string.Empty} = {Text ?? string.Empty}";
}
}
public class LabelGroup
{
private readonly List<Label> _labels;
public LabelGroup(List<Label> labels)
{
_labels = labels ?? throw new ArgumentNullException(nameof(labels));
}
/// <inheritdoc />
public override string ToString()
{
if (_labels.Any())
{
return string.Join(", ", _labels);
}
return string.Empty;
}
}
И затемиспользуйте некоторые Linq для получения данных:
string xml = "...."; // xml goes here
var groups = from instance in XDocument.Parse($"<root>{xml}</root>").Descendants("instance")
let labels = instance.Descendants("label")
where labels.Any() // ignore <instance> without <label> elements
let labelList = CreateLabels(labels)
select new LabelGroup(labelList);
foreach (var labelGroup in groups)
{
Console.WriteLine(labelGroup);
}
Метод CreateLabels:
private static List<Label> CreateLabels(IEnumerable<XElement> elements)
{
List<Label> labels = elements.Select(x => new Label {
Group = x.Element("group")?.Value,
Text = x.Element("text")?.Value
}).ToList();
return labels;
}
Обратите внимание, что вам нужно обернуть ваш XML в фиктивный элемент, чтобы избежать ошибки System.Xml.XmlException: 'There are multiple root elements. Line 19, position 2.'
какследует:
XDocument.Parse($"<root>{xml}</root>")
EDIT
Учитывая, что OP использует более старую версию .NET Framework (3.5), классы Label
и LabelGroup
должны быть изменены следующим образом.Остальная часть кода должна быть совместима с .NET 3.5:
public class Label
{
public string Group { get; set; }
public string Text { get; set; }
public override string ToString()
{
if (string.IsNullOrEmpty(Group))
{
return Text;
}
return string.Format("{0} = {1}", Group ?? string.Empty, Text ?? string.Empty);
}
}
public class LabelGroup
{
private readonly List<Label> _labels;
public LabelGroup(List<Label> labels)
{
if (labels == null)
{
throw new ArgumentNullException("labels");
}
_labels = labels;
}
public override string ToString()
{
if (_labels.Any())
{
return string.Join(", ", _labels.Select(x => x.ToString()).ToArray());
}
return string.Empty;
}
}