简体   繁体   English

需要使用Linq检索XML数据的帮助

[英]Need help retrieving XML data using Linq

I am trying to retrieve data from an XML file and return the parsed data in a list. 我正在尝试从XML文件中检索数据并在列表中返回已解析的数据。 Depending on what I use to access the data (Element or Attributes) I either get null (in case of Element) or something I cannot decipher (in case of Attributes). 根据我用来访问数据的内容(元素或属性),我会得到null(对于Element)还是无法解密(对于属性)。

XML Looks like this: XML看起来像这样:

<DATA_RESPONSE>
    <HEADER>
        <MSGID>IS20101P:091317125610:98::34:0</MSGID>
    </HEADER>
    <DATA>
        <ROW ID='IS20101P' PE_NAME='APP-029' PE_ID='4' CODE='4829' DATA='5,1,500,1'  />
        <ROW ID='IS20101P' PE_NAME='APPS-029' PE_ID='4' CODE='4829' DATA='4,1,500,1' />
        ...
    </DATA>
    <SUMMARY>
    </SUMMARY>
    <ERRORS>
    </ERRORS>
</DATA_RESPONSE>

I am using the following to get the data. 我正在使用以下方法来获取数据。 I read the file and store XML in a string and call a method with this string as argument: 我读取文件并将XML存储在字符串中,然后使用此字符串作为参数来调用方法:

public static Hashtable GetIDSData(string sXMLString)
{
    Hashtable result = new Hashtable();

    result.Add("Success", false);
    result.Add("ErrorMessage", "");
    result.Add("ID", "");
    result.Add("PE_NAME", "");
    result.Add("PE_ID", "");
    result.Add("CODE", "");
    result.Add("DATA", "");

    xmlDoc.InnerXml = sXMLString;
    XmlElement root = xmlDoc.DocumentElement;
    XDocument doc = XDocument.Parse(sXMLString);
    XmlNode node = xmlDoc.SelectSingleNode("DATA_RESPONSE/DATA"); 

    if (node != null)
    {
        var AddressInfoList = doc.Root.Descendants("ROW").Select(Address => new
        {
            ID = Address.Attributes("ID")?.ToString(),
            PEName = Address.Attributes("PE_NAME")?.ToString(),
            PEID = Address.Attributes("PE_ID")?.ToString(),
            Code = Address.Attributes("CODE")?.ToString(),
            Data = Address.Attributes("DATA")?.ToString(),
        }).ToList();

        foreach (var AddressInfo in AddressInfoList)
        {
            if (string.IsNullOrEmpty(AddressInfo.Code))
            {
                result["Success"] = false;
                result["ErrorMessage"] = "Invalid Code; code is empty.";
            }
            else
            {
                result["Success"] = true;
                result["ErrorMessage"] = "";
                result["ID"] = AddressInfo.ID;
                result["PE_NAME"] = AddressInfo.PEName;
                result["PE_ID"] = AddressInfo.PEID;
                result["CODE"] = AddressInfo.Code;
                result["DATA"] = AddressInfo.Data;
            }
        }
        return result;
    }

In Linq section, if I use Address.Element("ID").Value, I get null returned. 在Linq部分中,如果我使用Address.Element(“ ID”)。Value,则返回null。 There is no namespace used in XML. XML中没有使用名称空间。

First off, the GetIDSData() method does not compile as is, because at the line xmlDoc.InnerXml = sXMLString , xmlDoc has not been defined. 首先, GetIDSData()方法不会按GetIDSData()编译,因为在xmlDoc.InnerXml = sXMLString这一行中,尚未定义xmlDoc

I'm assuming you want xmlDoc to be an XmlDocument loaded with the contents of the sXMLString parameter, so I'm changing that line to: 我假设您希望xmlDoc是加载了sXMLString参数内容的XmlDocument ,所以我将该行更改为:

XmlDocument xmlDoc = new XmlDocument {InnerXml = sXMLString};

Also, your root variable is never used, so I removed it for clarity. 另外,您的root变量从未使用过,因此为了清楚起见,我将其删除。

Now as for the main part of your question, given your current syntax, you are calling .ToString() on a collection of attributes, which is obviously not what you want. 现在,对于问题的主要部分,鉴于当前的语法,您正在对属性集合调用.ToString() ,这显然不是您想要的。 To fix this, when you're iterating the AddressInfoList , You want to fetch the attribute values like: 为了解决这个问题,在迭代AddressInfoList ,您想要获取属性值,例如:

ID = Address.Attributes("ID")?.Single().Value

or 要么

ID = address.Attribute("ID")?.Value

...rather than Address.Attributes("ID")?.ToString() as you have above. ...而不是上面的Address.Attributes("ID")?.ToString()

You are not selecting values of attributes. 您没有选择属性值。 In your code you are selecting attributes. 在代码中,您正在选择属性。 Not sure what are you trying to achieve, but here is my modified version of your code that loads all elements into DataTable 不确定您要实现什么目的,但是这是我的代码的修改后的版本,可将所有元素加载到DataTable中

public static DataTable GetIDSData(string sXMLString)
{
  DataTable result = new DataTable();

result.Columns.Add("Success");
result.Columns.Add("ErrorMessage");
result.Columns.Add("ID");
result.Columns.Add("PE_NAME");
result.Columns.Add("PE_ID");
result.Columns.Add("CODE");
result.Columns.Add("DATA");

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.InnerXml = sXMLString;
XmlElement root = xmlDoc.DocumentElement;
XDocument doc = XDocument.Parse(sXMLString);
XmlNode node = xmlDoc.SelectSingleNode("DATA_RESPONSE/DATA");

if (node != null)
{
    var AddressInfoList = doc.Root.Descendants("ROW").Select(Address => new
    {
        ID = Address.Attributes("ID").Select(i=>i.Value) ,
        PEName = Address.Attributes("PE_NAME").Select(i=>i.Value),
        PEID = Address.Attributes("PE_ID").Select(i=>i.Value),
        Code = Address.Attributes("CODE").Select(i=>i.Value),
        Data = Address.Attributes("DATA").Select(i=>i.Value),
    }).ToList();



    AddressInfoList.ForEach(e => 
    {
        e.Code.ToList().ForEach(c =>
        {
            DataRow row = result.NewRow();
            if (!string.IsNullOrEmpty(c))
            {

                row["Success"] = true;
                row["ErrorMessage"] = "";
                row["ID"] = e.ID.First();
                row["PE_NAME"] = e.PEName.First();
                row["PE_ID"] = e.PEID.First();
                row["CODE"] = e.Code.First();
                row["DATA"] = e.Data.First();

            }
            else
            {
                row["Success"] = false;
                row["ErrorMessage"] = "Invalid Code; code is empty.";
            }
            result.Rows.Add(row);

    });});
    result.Dump();
    return result;
}
return result;

} }

And this is the result that you will get in your datatable. 这就是您将要进入数据表的结果。 在此处输入图片说明

 ID = Address.Attributes("ID")?.ToString(), 

您想使用Attribute(name) (不带s )来代替:

ID = Address.Attributes("ID")?.Value,

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM