如何使用Linq Lambda从给定密钥解析XML文件

时间:2018-07-04 11:42:17

标签: c# linq lambda xml-parsing

我正在尝试使用Linq和Lambda表达式解析xml文档,但需要帮助。

我要从中获取数据的节点是“ DiskDriveInfo”, 我也不确定如何继续下一个节点“ ResultCode i:nil =” true“”

我的代码:

var xml = XDocument.Parse(InXML);
var r = from x in xml.Elements("DiskDriveInfo")
                select new
                {
                    ResultCode = x.Element("ResultCode").Value,
                    ResultCodeDescription = 
                          x.Element("ResultCodeDescription").Value,
                    AirbagDetails = x.Element("AirbagDetails").Value,
                    ..
                    ..
                    WheelBase        = x.Element("WheelBase").Value              
};

,输入为:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Body>
    <GetConvergedDataRequestResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://autoinsight.trn.co.za/types">
      <ConvergedData xmlns:d4p1="http://schemas.datacontract.orgB2B.BusinessModels" i:type="ConvergedResults">
        <AccidentHistory i:nil="true" />
        <AlertInfo i:nil="true" />
        <CloneInfo i:nil="true" />
        <DiskDriveInfo>
          <ResultCode i:nil="true" />
          <ResultCodeDescription i:nil="true" />
          <AirbagDetails>DRIVER, PASSENGER</AirbagDetails>
...
...
<WheelBase>2460</WheelBase>
    </DiskDriveInfo>

Thx

2 个答案:

答案 0 :(得分:1)

这里有两个问题:

  • 您的元素位于名称空间“ http://autoinsight.trn.co.za/types”中,但您在查找它们时未指定名称空间
  • 您正在使用xml.Elements,它只会查找根元素;要查找任何后代,则应使用Descendants

所以您可能想要:

XNamespace ns = "http://autoinsight.trn.co.za/types";
var xml = XDocument.Parse(InXML);
var r = from x in xml.Descendants(ns + "DiskDriveInfo")
        select new
        {
            ResultCode = x.Element(ns + "ResultCode").Value,
            ResultCodeDescription = x.Element(ns + "ResultCodeDescription").Value,
            AirbagDetails = x.Element(ns + "AirbagDetails").Value,
            ..
            ..
            WheelBase = x.Element(ns + "WheelBase").Value              
        };

请注意,我可能不会为此使用查询表达式-我会直接调用Select

var r = xml
    .Descendants(ns + "DiskDriveInfo")
    .Select(x => new
    {
        ResultCode = x.Element(ns + "ResultCode").Value,
        ResultCodeDescription = x.Element(ns + "ResultCodeDescription").Value,
        AirbagDetails = x.Element(ns + "AirbagDetails").Value,
        ..
        ..
        WheelBase = x.Element(ns + "WheelBase").Value              
    });

如果您需要一个带有i:nil="true"的元素以返回null而不是一个空字符串,那么我将为XElement添加一个扩展方法:

private static XNamespace SchemaNamespace = "http://www.w3.org/2001/XMLSchema-instance";
public static string ValueOrNull(this XElement element)
{
    XAttribute nil = element.Attribute(SchemaNamespace + "nil");
    return (string) nil == "true" ? null : element.Value;
}

然后这样称呼它:

XNamespace ns = "http://autoinsight.trn.co.za/types";
var xml = XDocument.Parse(InXML);
var r = from x in xml.Descendants(ns + "DiskDriveInfo")
        select new
        {
            ResultCode = x.Element(ns + "ResultCode").ValueOrNull(),
            ResultCodeDescription = x.Element(ns + "ResultCodeDescription").ValueOrNull(),
            AirbagDetails = x.Element(ns + "AirbagDetails").ValueOrNull(),
            ..
            ..
            WheelBase = x.Element(ns + "WheelBase").ValueOrNull()             
        };

答案 1 :(得分:0)

您只需要根据xml文件创建类,就可以从下面的代码中编写代码,下面是直接将xml转换为类对象的函数

    public T DeserializeData(string dataXML)
    {
         XmlDocument xDoc = new XmlDocument();
         xDoc.LoadXml(dataXML);
         XmlNodeReader xNodeReader = new XmlNodeReader(xDoc.DocumentElement);
         XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
         var modelData = xmlSerializer.Deserialize(xNodeReader);
         T deserializedModel = (T)modelData ;
         return deserializedModel;
    }