2017-02-15 25 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

相关问题