2017-02-15 6 views
-1

EDIT: Предлагаемые ответы для меня пока не работают. Может быть, мой пример немного вводит в заблуждение. Я обновил XML, а также ожидаемую строку для справки. Я могу иметь несколько вхождений узлов с разными уровнями, и на каждом уровне у меня может быть один или несколько дочерних элементов.Как читать значения атрибутов из XML и объединять их с одной строкой

У меня есть XML-файл со следующей структурой:

<VariableCollection> 
    <Variable Name="Level1"> 
     <Variable Name="Level2"> 
       <Variable Name="Level3"> 
        <Variable Name="Level4"/> 
        <Variable Name="Level41"/> 
       </Variable> 
     </Variable> 
    </Variable> 
    <Variable Name="Level11"> 
     <Variable Name="Level21"> 
       <Variable Name="Level31"> 
        <Variable Name="Level41"/> 
        <Variable Name="Level42"/> 
        <Variable Name="Level43"/> 
       </Variable> 
     </Variable> 
    </Variable> 
    <Variable Name="Level1"> 
      <Variable Name="Level2"> 
       <Variable Name="Level3"/> 
      </Variable> 
    </Variable> 
    <Variable Name="Level11"> 
      <Variable Name="Level21"> 
       <Variable Name="Level31"/> 
      </Variable> 
    </Variable> 
    <Variable Name="Level1"> 
      <Variable Name="Level2"/> 
    </Variable> 
    <Variable Name="Level11"> 
      <Variable Name="Level21"/> 
    </Variable> 
</VariableCollection> 

Так у меня есть узлы с различными структурированными подуровней/дочерних узлов. Что я хочу сделать, так это прочитать весь файл, используя LINQ to XML, и получить одну строку на «главный узел», созданный из атрибута «Имя» каждого «под-узла». Результат должен выглядеть так:

string1 = "Level1.Level2.Level3.Level4" 
string11 = "Level1.Level2.Level3.Level41" 

string2 = "Level11.Level21.Level31.Level41" 
string22 = "Level11.Level21.Level31.Level42" 
string23 = "Level11.Level21.Level31.Level43" 

string3 = "Level1.Level2.Level3" 
string3 = "Level11.Level21.Level31" 

string4 = "Level1.Level2" 
string5 = "Level11.Level21" 

Моя проблема в том, что я понятия не имею, как я могу это сделать. Может ли кто-нибудь показать мне пример, как я могу это сделать?

ответ

1

Я использовал подход «снизу вверх». Первый шаг - найти переменные, которые не имеют вложенных элементов (lastLvl в коде). Второй шаг - переходить к именам root и concatenate. Следующий код

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml.Serialization; 
using System.Xml; 
using System.Xml.Linq; 
using System.Xml.XPath; 
using System.Collections; 

public class Program 
{ 
    public static void Main() 
    { 
     var @s = 
@"<VariableCollection> 
    <Variable Name='Level1'> 
     <Variable Name='Level2'> 
       <Variable Name='Level3'> 
        <Variable Name='Level4'/> 
        <Variable Name='Level41'/> 
       </Variable> 
     </Variable> 
    </Variable> 
    <Variable Name='Level11'> 
     <Variable Name='Level21'> 
       <Variable Name='Level31'> 
        <Variable Name='Level41'/> 
        <Variable Name='Level42'/> 
        <Variable Name='Level43'/> 
       </Variable> 
     </Variable> 
    </Variable> 
    <Variable Name='Level1'> 
      <Variable Name='Level2'> 
       <Variable Name='Level3'/> 
      </Variable> 
    </Variable> 
    <Variable Name='Level11'> 
      <Variable Name='Level21'> 
       <Variable Name='Level31'/> 
      </Variable> 
    </Variable> 
    <Variable Name='Level1'> 
      <Variable Name='Level2'/> 
    </Variable> 
    <Variable Name='Level11'> 
      <Variable Name='Level21'/> 
    </Variable> 
</VariableCollection>"; 
 var xml = XElement.Parse(@s); 

     var lastLvl = xml.Descendants("Variable").Where(x => !x.HasElements); 

     Console.WriteLine(String.Join(Environment.NewLine, lastLvl)); 

     var names = lastLvl.Select(x => String.Join(".", x.AncestorsAndSelf("Variable").Select(e=>(string)e.Attribute("Name")).Reverse())); 

     Console.WriteLine(); 
     Console.WriteLine(String.Join(Environment.NewLine, names)); 
    } 
} 

формирует выходной сигнал:

lastLevel:

<Variable Name="Level4" /> 
<Variable Name="Level41" /> 
<Variable Name="Level41" /> 
<Variable Name="Level42" /> 
<Variable Name="Level43" /> 
<Variable Name="Level3" /> 
<Variable Name="Level31" /> 
<Variable Name="Level2" /> 
<Variable Name="Level21" /> 

имена:

Level1.Level2.Level3.Level4 
Level1.Level2.Level3.Level41 
Level11.Level21.Level31.Level41 
Level11.Level21.Level31.Level42 
Level11.Level21.Level31.Level43 
Level1.Level2.Level3 
Level11.Level21.Level31 
Level1.Level2 
Level11.Level21 

попробовать Demo скрипт

0

Вы можете использовать XElement для разбора и траверс документы, как это:

string xml = @" 
<VariableCollection> 
    <Variable Name=""Level1""> 
     <Variable Name=""Level2""> 
       <Variable Name=""Level3""> 
        <Variable Name=""Level4""/> 
       </Variable> 
     </Variable> 
    </Variable> 
    <Variable Name=""Level1""> 
      <Variable Name=""Level2""> 
       <Variable Name=""Level3""/> 
      </Variable> 
    </Variable> 
    <Variable Name=""Level1""> 
      <Variable Name=""Level2""/> 
    </Variable> 
</VariableCollection> 
"; 

var root = XElement.Parse(xml); 

var stringList = new List<string>(); 
foreach (var child in root.Elements()) 
{ 
    string value = child.DescendantsAndSelf() 
     .Select(i => i.Attribute("Name").Value) 
     .Aggregate((a, b) => a + "." + b); 

    stringList.Add(value); 
} 

foreach (var str in stringList) 
    Console.WriteLine(str.ToString()); 

Если вы хотите загрузить из файла, то нам этот код:

var root = XElement.Load("filepath"); 
2

Вы можете сделать следующее :

var root = XDocument.Parse(xml); 
var strings = root.Root.Elements() 
    .Select(e => String.Join(".", e.DescendantsAndSelf().Select(c => (string)c.Attribute("Name")))) 
    .ToArray(); 

Здесь я прокручиваю непосредственные дочерние элементы корневого элемента <VariableCollection> с XElement.Elements(), то для каждого элемента рекурсивно спускаем свою иерархию элементов с помощью DescendantsAndSelf(), чтобы выделить атрибуты Name во вложенном запросе, а затем объединить значения с String.Join().

Пример fiddle.

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