linq xml所有内部节点

时间:2013-08-20 08:04:33

标签: 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>

如何仅选择那些(和所有子节点/元素)元素(“userid”)。value ==“U01”和元素(“name”)。值==“Tom Jones”等即我想要结果:

 <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

这可能吗?

3 个答案:

答案 0 :(得分:0)

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

无论如何,这部分代码可以满足您的需求。只需声明userName和userid:

//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();

答案 1 :(得分: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。

答案 2 :(得分: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");