简体   繁体   中英

Get all the attribute values by attribute name from XML file using Linq to XML

I have an XML file and I have to extract all the attribute values from XML. I have tried the below one but I need it in Linq. Can anyone guide me how to do this.

Sample XML

<MapFile>
 <Import>
  <field name1="BorrowId" name2="EMPLID" />
  <field name1="Firstname" name2="COMPLETENAME" />
  <field name1="Address" name2="Address" Reference="Location" />
 </Import>
 <Location>
  <Lookup Key="CC" Replace="1" />
  <Lookup Key="CE" Replace="2" />
 </Location>
</MapFile>

Expected Result

[0]:
  CurrentVal = "BorrowId"
  NewVal = "EMPLID"
  Reference = null
  ReferenceList = null
[1]:
  CurrentVal = "Firstname"
  NewVal = "COMPLETENAME"
  Reference = null
  ReferenceList = null
[2]:
  CurrentVal = "Address"
  NewVal = "Address"
  Reference = "Location"
  ReferenceList = [0]:
                       Key = "CC"
                       Value = "1"
                  [1]:
                       Key = "CE"
                       Value = "2"

Code

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(@sPath);
var attrValues = xmlDoc.GetElementsByTagName("field");
List<MapFileModel> MapFileMod = new List<MapFileModel>();
foreach (XmlNode x in attrValues)
{
   MapFileModel _objMapFile = new MapFileModel();
   if (x.Attributes["name1"] != null)
   {
      _objMapFile.CurrentVal = x.Attributes["name1"] != null ? x.Attributes["name2"].Value : null;
      _objMapFile.NewVal = x.Attributes["name2"] != null ? x.Attributes["name2"].Value : null;
      _objMapFile.Reference = x.Attributes["Reference"] != null ? x.Attributes["Reference"].Value : null;
    }
   MapFileMod.Add(_objMapFile);
}

Okay, so it looks like you want something like this, which loads all the field elements in the Import just-below-root element, then loads the reference lists by finding every element which isn't Import .

var doc = XDocument.Load("foo.xml");
var replacements = doc
    .Root
    .Element("Import")
    .Elements("field")
    .Select(x => new Replacement {
        CurrentValue = (string) x.Attribute("name1"),
        NewValue = (string) x.Attribute("name2"),
        Reference = (string) x.Attribute("reference")
    })
    .ToList();

var referenceLists = doc
    .Root
    .Elements()
    .Where(f => f.Name.LocalName != "Import")
    .ToDictionary(
        x => x.Name.LocalName,
        x => x.Elements("Lookup")
              .Select(l => new KeyValuePair<string, string>(
                   (string) l.Attribute("Key"),
                   (string) l.Attribute("Replace"))
              .ToList()
    );

You'd then look up the Replacement.Reference in ReferenceLists to get the key/value pair list.

Something like this? https://forums.asp.net/t/1964585.aspx?how+to+read+xml+elements+using+linq+in+c+net+recursively+

Must be improved but :

 string strFilename = "/Message.xml";
            strFilename = Server.MapPath(strFilename);
            XmlDocument xmlDoc = new XmlDocument();

            if (File.Exists(strFilename))
            {
                XmlTextReader rdrXml = new XmlTextReader(strFilename);

                do
                {
                    switch (rdrXml.NodeType)
                    {
                        case XmlNodeType.Text:

                            //Console.WriteLine("{0}", rdrXml.Value);
                            Response.Write(rdrXml.Value + "<br/>");
                            break;
                    }
                } while (rdrXml.Read());
            }

See below is a generic program that parses the xml string and recursively prints attribute name and value. I hope you can check if the name is a reference value per your requirement and go from over there..

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication9
{
  class Program
  {
    static void Main(string[] args)
    {
        string xmlstring = @"<MapFile>
                                 <Import>
                                  <field name1=""BorrowId"" name2=""EMPLID"" />
                                  <field name1=""Firstname"" name2=""COMPLETENAME"" />
                                  <field name1=""Address"" name2=""Address"" Reference=""Location"" />
                                 </Import>
                                 <Location>
                                  <Lookup Key=""CC"" Replace=""1"" />
                                  <Lookup Key=""CE"" Replace=""2"" />
                                 </Location>
                                </MapFile>";
        XElement xmlTree = XElement.Parse(xmlstring);
        ParseChildElement(xmlTree);
        Console.ReadLine();
    }
    static void ParseChildElement(XElement xmlTree)
    {
        PrintAttributes(xmlTree);
        foreach(XElement element in xmlTree.Elements())
        {
            ParseChildElement(element);
        }
    }

    static void PrintAttributes(XElement xmlTree)
    {
        foreach (XAttribute attr in xmlTree.Attributes())
        {
            string[] attribArray = attr.ToString().Split('=');
            if (attribArray.Length > 1)
                Console.WriteLine(string.Format(@" {0} = {1}", attr.Name, attr.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