【问题标题】:LINQ XML - Retrieve unknown name and value from XElementLINQ XML - 从 XElement 检索未知名称和值
【发布时间】:2014-06-30 10:21:26
【问题描述】:

我目前正在努力解析以下 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 Parsing 方法的空白吗?

//
    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();
}

【问题讨论】:

  • XML 应该如何映射到您的类中?对于您的示例 XML,您希望在 NameTypeValue 中包含什么内容?
  • @Mark - 名称应该是字段名称,例如“failure_type”。 Value 应该是值,例如“Blah”,Type 应该是 xsd 中指定的类型 - 在这种情况下它是一个字符串。前者比后者更容易,我可以在 LINQ 之外解析它们,但我更喜欢更一致的解决方案。

标签: c# xml linq xsd


【解决方案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 中得到以下结果:

【讨论】:

  • 谢谢。我不知道你可以像这样使用模式进入它,这非常有帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-21
  • 1970-01-01
  • 2017-05-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多