简体   繁体   中英

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. 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).

XML Looks like this:

<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:

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. There is no namespace used in XML.

First off, the GetIDSData() method does not compile as is, because at the line xmlDoc.InnerXml = sXMLString , xmlDoc has not been defined.

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:

XmlDocument xmlDoc = new XmlDocument {InnerXml = sXMLString};

Also, your root variable is never used, so I removed it for clarity.

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. To fix this, when you're iterating the AddressInfoList , You want to fetch the attribute values like:

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

or

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

...rather than Address.Attributes("ID")?.ToString() as you have above.

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

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,

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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