我正在尝试读取 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>
字段类由
FieldProperties
标签表示。要确定某个字段是否有选项,您需要检查它的 FieldType
是否为 9。如果 FieldType
为 9,那么您必须去寻找 FieldOptions
,它链接到 FieldName
标签FieldProperties
标签。
我不知道如何编写这样的查询。我目前所拥有的是循环遍历所有
FieldProperties
,然后填充字段属性。但我不知道如何检查字段类型是否为 9,如果是 9,则去获取 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;
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.SelectMany 展平为 {Field, Option} 对的流
3.GroupBy Field 来合并选项