【问题标题】:Search Elements from Xml matching with a list of ids从 Xml 中搜索与 id 列表匹配的元素
【发布时间】:2017-01-26 07:53:19
【问题描述】:

您好,我有一个包含书籍详细信息的 xml。 xml的结构是-

<Root>
    <Books>
        <Book>
            <BookId>1</BookId>
            <Title>Book 1</Title>
            <LanguageId>1</LanguageId>
            <Genres>2,3</Genres>
            <BookType>1</BookType>
            <Description>Lorem Ipsum</Description>
        </Book>
        <Book>
            <BookId>3</BookId>
            <Title>Book 3</Title>
            <LanguageId>3</LanguageId>
            <Genres>12,23</Genres>
            <BookType>2</BookType>
            <Description>Lorem Ipsum</Description>
        </Book>
        <Book>
            <BookId>3</BookId>
            <Title>Book 2</Title>
            <LanguageId>2</LanguageId>
            <Genres>1,13</Genres>
            <BookType>2</BookType>
            <Description>Lorem Ipsum</Description>
        </Book>
         <Book>
            <BookId>4</BookId>
            <Title>Book 4</Title>
            <LanguageId>2</LanguageId>
            <Genres>1,13</Genres>
            <BookType>2</BookType>
            <Description>Lorem Ipsum</Description>
        </Book>
    </Books>
</Root>

一本书可以有多个流派 ID,可以有多种语言。 我有一个流派 ID 列表、语言列表和书籍类型列表。

我想获取所有类型 ID、语言 ID 和书籍类型与该列表匹配的书籍。

我为此使用了 LINQ 查询,因为循环遍历所有书籍 xml 节点会更有效-

  List<XElement> elems = xldoc.Root.Descendants("Books")
                                     .Descendants("Book")
                                     .Where(x=> 
                                   (listofgenres.Contains(x.Element("GenreId").Value)) &&  
                                   (listoflanguages.Contains(x.Element("LanguageId").Value)) &&
                                   (listofbooktypes.Contains(x.Element("BookType").Value)))
                                    .ToList();

但它并没有如我所愿地获取结果。我做错了什么???

如果假设我有一个 bookIds 列表,例如 1、3、4、2,并且我想以与我的列表相同的顺序获取这些 id 的书,那么 linq 的另一种方式是什么。现在,我通过遍历所有 xml 节点并添加到集合中,逐个按 id 获取书籍。

【问题讨论】:

    标签: c# .net xml linq list


    【解决方案1】:

    您的 xml 中没有任何 GenreId。你有Genres,这是逗号分隔的流派列表。 我想你想做这样的事情:

    List<XElement> elems = xldoc.Root.Descendants("Books")
            .Descendants("Book")
            .Where(x=> (listofgenres.Intersect(x.Element("Genres").Value.Split(',')).Any())
                       && (listoflanguages.Contains(x.Element("LanguageId").Value)) 
                       && (listofbooktypes.Contains(x.Element("BookType").Value)))
            .ToList();
    

    【讨论】:

    • 是的,流派是用逗号分隔的流派 ID。
    • @ThirueswaranRajagopalan 谢谢。我在 LInqPad 中有 sam,问题是,我假设,预期的交集可能是所有类型都应该在 listofgenres 中。
    • 如果我有一个 id 列表并且我想使用 linq 从 xml 中获取它们的元素,顺序与我的列表相同,那么我必须进行哪些更改。通常我会遍历我所有的 xml 节点并按 id 逐个获取元素,然后将其添加到集合中。
    • @Maksim Simkin 我有一个 id 列表,我必须比较的节点是逗号分隔的 id,我很难检索它
    • @Sonali 你可以为它创建另一个问题吗?对于这个,您已经接受了答案。
    【解决方案2】:

    很简单:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    using System.Xml;
    using System.Xml.Linq;
    
    
    
    namespace ConsoleApplication43
    {
        class Program
        {
            const string FILENAME = @"c:\temp\test.xml";
            static void Main(string[] args)
            {
                List<int> order = new List<int>() { 1, 3, 4, 2 };
                XDocument doc = XDocument.Load(FILENAME);
    
                List<XElement> books = doc.Descendants("Book").OrderBy(x => order.IndexOf((int)x.Element("BookId"))).ToList();
            }
        }
    
    }
    

    【讨论】:

    • 我使用了你的逻辑,但它返回了所有的书节点List&lt;int&gt; order = new List&lt;int&gt;() { 1, 3, };List&lt;XElement&gt; books = xldoc.Root.Element("Books").Descendants("Book").OrderBy(x =&gt; bookids.IndexOf((int)x.Element("BookId"))).ToList();
    • 然后你需要添加: Where(x => order.Contains((int)x.Element("BookId"))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-18
    • 1970-01-01
    • 2013-09-11
    • 2018-04-15
    • 2021-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多