2013-08-20 68 views
1

我有XML文档:LINQ XML中的所有内部节点

<users> 
     <user_tuple> 
      <userid>U01</userid> 
      <code> 
      <name>Tom Jones</name> 
      </code> 
      <rating>B</rating> 
     </user_tuple> 
     <user_tuple> 
      <userid>U02</userid> 
      <code> 
      <name>Mary Doe</name> 
      </code> 
      <rating>A</rating> 
     </user_tuple> 
     <user_tuple> 
      <userid>U03</userid> 
      <code> 
      <name>Dee Linquent</name> 
      </code> 
     <rating>D</rating> 
     </user_tuple> 
</users> 

如何我只选择那些(和所有子节点/元素),其中元素(“用户id”)值==“U01”和元素。 ( “名称”)值== “汤姆·琼斯” 等即我想要的结果:

<user_tuple> 
     <userid>U01</userid> 
     <code> 
     <name>Tom Jones</name> 
     </code> 
     <rating>B</rating> 
    </user_tuple> 

我使用C#

public void searchInfo(string rootNode, string Element1Name, string Element2Name, string Element1Val, string Element2Val){ 

////// Select rootNode and all descend nodes 

    var res = root.Elements("rootNode") 
     .Where(
      x => 
      (string)x.Element(Element1Name) == Element1Val&& 
      (string)x.Element(Element2Name) == Element2Val) 
     ).ToList(); 
///////////  

foreach (var node in res){ 
Debug.Writeline("Name {0} Value {1}", node.Name, node.Value) 

} 

例子:

searchInfo("rootNode","userid","code", "U01", "Tom Jones") 

res = <userid>U01</userid> 
      <code> 
      <name>Tom Jones</name> 
      </code> 
      <rating>B</rating> 

and result: 
userid U01 
name Tom Jones 
rating B 

这可能吗?

回答

0

首先我建议你将信息从内部值移到属性,如果有可能的,从<code><user_tuple><user_tuple userid="U01" name=Tom Jones rating="B" /> 或者至少移动<name> XML节点,因为这对我来说没有任何意义在那里。

无论如何,这部分代码可以满足您的需求。刚刚宣布userName和用户ID:

//Load your xml file 
var xdoc = XDocument.Load(@"path\\to\\users.xml"); 
var entity =(from user in xdoc.Descendants("user_tuple") 
      let userIdElem = user.Element("userid") 
      let codeElem = user.Element("code") 
      let nameElem = (codeElem != null) ? codeElem.Element("name") : null 
      let rating = user.Element("rating") 
      where userIdElem != null && nameElem != null && nameElem.Value.Equals(userName) && userIdElem.Value.Equals(userid) 
      select new 
      { 
       UserId = userIdElem.Value, 
       UserName = nameElem.Value, 
       Rating = (rating == null) ? string.Empty : rating.Value 
      }).FirstOrDefault(); 
0

此:

var res = (from p in xml2.Root.Elements() 
      where (string)p.Element("userid") == "U01" 
      let code = p.Element("code") 
      where code != null 
      where (string)code.Element("name") == "Tom Jones" 
      select p).ToArray(); 

// note that the (string) converter will automatically handle missing elements 

完成所有的各种null检查。显然你必须把你的变量,而不是常量。 xml2是你的xml。

0

因此,与LINQ-2-XML,

// if users is not the root 
var users = root.Element("users"); 

var filtered = users.Elements().Where(e => 
    { 
     if ((string)e.Element("userid")) != "U01") 
     { 
      return false; 
     } 

     var code = e.Element("code"); 

     if (code == null) 
     { 
      return false; 
     } 

     if ((string)code.Element("name") != "Tom Jones") 
     { 
      return false; 
     } 

     return true; 
    }); 

在回应的意见,你可以投影数据转换成你想要的类型,我会让它匿名的现在。

var projectedAndFiltered = users.Elements.Select(e => 
    { 
     string name; 
     var code = e.Element("code"); 
     if (code != null) 
     { 
      name = (string)code.Element("name"); 
     } 

     return new 
      { 
       Id = (string)e.Element("userid"), 
       Name = name, 
       Rating = (string)e.Element("rating") 
      }; 
    }) 
    .Where(tuple => tuple.Id == "U01" && tuple.Name == "Tom Jones"); 
+0

Гарик希望有一个'Tuple' /'object'结果: (_and结果:用户ID U01,名汤姆·琼斯,等级B.这是可能的_?) 当你的片断不提供评分值 (即你可以用'out string rating' paramenter将它包装在一个函数中)。 – Salaros

+1

@Salaros yep,就像我想的那样。 – Jodrell