2017-02-15 58 views
-1

編輯:到目前爲止,建議的答案對我來說不起作用。也許我的例子有點誤導。我已經更新了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)。第二步是回溯到根目錄並連接名稱。下面的代碼

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

相關問題