提问人:Brendan Vogt 提问时间:9/20/2023 更新时间:9/20/2023 访问量:29
C# Linq to XML 获取父对象和子对象
C# Linq to XML getting of parent and child objects
问:
我正在尝试读取XML文件,然后将值填充到C#类(父对象和子对象)中。为了简洁起见,我省略了很多代码。我正在尝试通过Linq to XML来实现这一点。
我创建了以下类,该类将是父类,该类还将承载子字符串对象的列表:
public class Field
{
public string Name { get; set; } = string.Empty;
public List<string> Options { get; set; } = new();
public FieldType Type { get; set; } = 0;
}
因此,一个字段可以包含以下 2 项内容中的 1 项:
- 它可以有一个空的字符串选项列表
- 或者它可以有一个字符串选项列表
XML是以一种有趣的方式完成的,我无法更改它,我只需要读入它并填充类和字符串对象(如果有的话),然后将此列表返回到前端进行进一步处理。
简化形式的 XML 文件:
<FieldProperties>
<FieldName>Question 1</FieldName>
<FieldType>1</FieldType>
</FieldProperties>
<FieldProperties>
<FieldName>Dietaries</FieldName>
<FieldType>9</FieldType>
</FieldProperties>
<FieldProperties>
<FieldName>Question 2</FieldName>
<FieldType>1</FieldType>
</FieldProperties>
<FieldProperties>
<FieldName>Transport</FieldName>
<FieldType>9</FieldType>
</FieldProperties>
<FieldOptions>
<FieldName>Dietaries</FieldName>
<Option>Dietary option 1</Option>
</FieldOptions>
<FieldOptions>
<FieldName>Dietaries</FieldName>
<Option>Dietary option 2</Option>
</FieldOptions>
<FieldOptions>
<FieldName>Dietaries</FieldName>
<Option>Dietary option 3</Option>
</FieldOptions>
<FieldOptions>
<FieldName>Transport</FieldName>
<Option>Transport option 1</Option>
</FieldOptions>
<FieldOptions>
<FieldName>Transport</FieldName>
<Option>Transport option 2</Option>
</FieldOptions>
字段类由标记表示。要确定字段是否有选项,您需要检查它是否具有 9。如果是 9,那么你必须去寻找,这与标签的标签相关联。FieldProperties
FieldType
FieldType
FieldOptions
FieldName
FieldProperties
我不知道如何编写这样的查询。我目前所拥有的是遍历所有字段属性,然后填充字段属性。但是我不知道如何检查字段类型是否为 9,如果为 9,则去获取子对象列表,然后填充 Options 属性。FieldProperties
FieldOptions
这是我目前拥有的:
XDocument xDocument = XDocument.Parse(xmlFields);
XNamespace xNamespace = "http://tempuri.org/FieldDefinition.xsd";
List<Field> fields =
xDocument.Descendants(xNamespace + "FieldProperties")
.Select(fieldProperties => new Field
{
Name = (string)fieldProperties.Element(xNamespace + "FieldName")!.Value,
Type = (FieldType)Int32.Parse(fieldProperties.Element(xNamespace + "FieldType")!.Value)
}).ToList();
return fields;
答:
0赞
sep7696
9/20/2023
#1
var fields = xDocument.Root
.Elements(xNamespace + "FieldProperties")
.Select(fp => new Field {
Name = (string)fp.Element(xNamespace + "FieldName"),
Type = (FieldType)int.Parse(fp.Element(xNamespace + "FieldType")!.Value)
})
.GroupJoin(
xDocument.Root.Elements(xNamespace + "FieldOptions"),
f => f.Name,
fo => (string)fo.Element(xNamespace + "FieldName"),
(f, fo) => new { Field = f, Options = fo })
.SelectMany(x =>
x.Field.Type == FieldType.Options
? x.Options.Select(o => new { x.Field, Option = (string)o.Element(xNamespace + "Option")! })
: new { x.Field })
.GroupBy(x => x.Field)
.Select(g =>
{
var field = g.Key;
if (field.Type == FieldType.Options)
{
field.Options = g.Select(x => x.Option).ToList();
}
return field;
})
.ToList();
1.GroupJoin将字段与其对应的选项匹配
2.选择Many以平展成{Field, Option}对的流
3.GroupBy 字段以合并选项
评论
FieldOptions
Type
FieldOptions
Options