LINQ XML - 从XElement中检索未知的名称和值

时间:2014-06-30 10:21:27

标签: c# xml linq xsd

我目前正在努力解析以下XML / XSD。

我的XSD中有一个“字段”列表,必须是以下之一:

<xs:element name="Field">
    <xs:annotation>
        <xs:documentation>Element to describe a selection by specified field values (decoded values).</xs:documentation>
    </xs:annotation>
    <xs:complexType>
        <xs:attribute name="subsystem_ident" type="xs:string" />
        <xs:attribute name="failure_type" type="xs:string" />
        <xs:attribute name="failure_type_code" type="xs:unsignedShort" />
        <!-- list continues -->
    </xs:complexType>
</xs:element>

我有另一个包含这些字段的元素:

<xs:element name="Include">
    <xs:complexType>
        <xs:sequence>
            <xs:choice maxOccurs="unbounded">                   
                <xs:element ref="Field" />
                <xs:element ref="Time"/>
            </xs:choice>
        </xs:sequence>
    </xs:complexType>
</xs:element>

所以在XML中看起来像是:

 <Include>
   <Field failure_type="Blah" />
   <Field failure_type_id="2" />
 </Include>

现在,因为我真的不知道我所获得的每个字段的元素名称,所以我很难解析它们。我也在努力找到我需要搜索的内容才能做到这一点。我的字段类只有三个属性:

public string Name { get; set; } // Should ultimately be an enum.
public Type Type { get; set; }
public string Value { get; set; }

有人可以帮我填写XML解析方法的空白吗?

//
    Include = RetrieveFields(matchExpElement.Elements("Match").Elements("Include").Elements("Field")),
//

private List<Field> RetrieveFields(IEnumerable<XElement> fieldElements)
{          
    var fields = from x in fieldElements
                 select new Field()
                 {
                     Name = 
                     Type = 
                     Value = 
                 };

     return fields.ToList();
}

1 个答案:

答案 0 :(得分:1)

为了获取属性的模式类型信息,您首先需要针对模式validate your XML并使其构建后模式验证信息集(Validate的最后一个参数法)。

var schemas = new XmlSchemaSet();
schemas.Add("", @"C:\Path\To\Your\schema.xsd");
var xml = @"
    <Match>
        <Include>
            <Field failure_type='Blah' />
            <Field failure_type_code='2' />
        </Include>
    </Match>
";
var doc = XDocument.Parse(xml);
doc.Validate(schemas, (s, e) => { Console.WriteLine(e); }, true);

然后,您可以在LINQ to XML查询中引用此信息以构建Field个对象 - 请注意GetSchemaInfo

var fields =
    from f in doc.Elements("Match").Elements("Include").Elements("Field")
    let attr = f.Attributes().First()
    select new Field() {
        Name = attr.Name.LocalName,
        Type = attr.GetSchemaInfo()
                .SchemaAttribute.AttributeSchemaType.Datatype.ValueType,
        Value = attr.Value
    };

我在LINQPad中得到以下结果:

LINQPad Results