2016-10-24 2 views
-1

У меня есть XML-файл, и мне нужно извлечь все значения атрибутов из XML. Я попробовал следующее, но мне нужно это в Linq. Может ли кто-нибудь вести меня, как это сделать.Получите все значения атрибутов по имени атрибута из файла XML, используя Linq to XML.

Пример 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> 

Ожидаемый результат

[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" 

Код

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); 
} 
+0

Ну, я хотел бы начать с помощью LINQ к XML, который является * много * более чистый API, чем 'XmlDocument', и многое другое LINQ. Теперь, судя по вашему коду, похоже, что у вас больше требований, чем «я должен извлечь все значения атрибутов» - пожалуйста, выражайте их в своем вопросе. Пока неясно, что именно вы просите в данный момент. –

+0

К сожалению, я не видел никаких других требований, кроме извлечения количества значений атрибутов. – DonMax

+0

Тогда почему ваш код имеет все эти строковые литералы для поиска * конкретных * атрибутов? Простое извлечение «всех значений атрибутов» так же просто, как 'doc.Descendants(). SelectMany (x => x.Attributes(). Выберите (a => a.Value))'. Я подозреваю, что это не то, что вы хотите - это просто даст вам «IEnumerable » - последовательность всех значений атрибутов. Это поможет, если вы предоставите короткий образец XML-документа и ожидаемый результат ... –

ответ

0

Что-то вроде этого? https://forums.asp.net/t/1964585.aspx?how+to+read+xml+elements+using+linq+in+c+net+recursively+

Должен быть улучшен, но:

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

Итак, похоже, что вы хотите что-то вроде этого, который загружает все field элементов в Import точно ниже корневом элементе, а затем загружает ссылку списков путем нахождения каждого элемента, который не является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() 
    ); 

Вы бы тогда посмотреть на Replacement.Reference в ReferenceLists, чтобы получить список пар ключ/значение.

0

См. Ниже общую программу, которая анализирует строку xml и рекурсивно печатает имя и значение атрибута. Я надеюсь, что вы можете проверить, является ли имя эталонного значения согласно вашему требованию и идти оттуда ..

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

}

Смежные вопросы