Linq选择字母之间的范围,例如。 A-E

时间:2009-11-19 14:45:29

标签: c# asp.net linq-to-xml

我想从xml文件中创建一个列表,其中只显示两个字母之间的值。例如,仅显示匹配记录,其中标题的第一个字符在“A”到“E”的范围内。

我的第一个基本方法是

where item.Element("title").Value >= "A" && item.Element("title").Value < "E"

当然这不起作用,因为这些运算符不能应用于字符串。 我尝试使用string.compare但没有运气。

有人能举例说明如何实现此查询吗?

欢呼声, 特里

更新:下面是读取xml的代码。

var simpleListSource = (from item in doc.Descendants("item")
    where item.Element("title").Value[0] >= 'A' && item.Element("title").Value[0] < 'E'
    orderby item.Element("title").Value
      select new
          {
            title = item.Element("title").Value,
            description = item.Element("description").Value,
            image = item.Element("image").Value,
            type = item.Element("type").Value,
            imagelink = item.Element("imagelink").Value

          }).ToList();

    rptGetItems.DataSource = simpleListSource;
    rptGetItems.DataBind();

和xml ......

  <item>
        <title>A test</title>
        <titlelong>A</titlelong>
        <type>test</type>
        <description>
        Some description

        </description>
        <image>includes/images/test.jpg</image>
        <imagelink>http://somesite.com</imagelink>

    </item>
    <item>
        <title>E test2</title>
        <titlelong>E</titlelong>
        <type>test</type>
        <description>
        Another sample

        </description>
        <image>includes/images/test.jpg</image>
        <imagelink>http://somesite.com</imagelink>

    </item>

6 个答案:

答案 0 :(得分:4)

使用字符并将它们与标题中的第一个字符进行比较:

where item.Element("title").Value[0] >= 'A' 
      && item.Element("title").Value[0] < 'E'

您可能想要测试空标题...

    bool TitleInRange(string title)
    {
        if (title == null || title.Trim() == string.Empty)
            return false;

        return (title[0] >= 'A' && title[0] <= 'E')
            || (title[0] >= 'a' && title[0] <= 'e');
    }

    ...
    where TitleInRange(item.Element("title").Value)

(更新)

您的代码按预期工作。只需将< E更改为<= E即可。尝试将标题打印到控制台:

        foreach (var item in simpleListSource)
        {
            Console.WriteLine("{0}", item.title);
        }

您的问题必须与数据绑定有关。

答案 1 :(得分:2)

where "ABCDE".Contains(item.Element("title").Value[0])

答案 2 :(得分:1)

where Enumerable.Range('A','E').Select(x => (char) x).Contains(title[0])

(未测试的)

答案 3 :(得分:0)

尝试:

where item.Element("title").Value[0] >= 'A' && item.Element("title").Value[0] < 'E'

现在你要将char与char进行比较,它可以使用普通的比较运算符。

编辑:这是一个示例程序:

using System;
using System.Collections.Generic;
using System.Xml.Linq;
using System.Linq;

namespace TestIdeas
{
    class Program
    {
        static void Main(string[] args)
        {
            XElement i1 = XElement.Parse(@" <item>
                                                <title>A test</title>
                                                <titlelong>A</titlelong>
                                                <type>test</type>
                                                <description>
                                                    Some description
                                                </description>
                                                <image>includes/images/test.jpg</image>
                                                <imagelink>http://somesite.com</imagelink>

                                            </item>");

            XElement i2 = XElement.Parse(@" <item>
                                                <title>E test2</title>
                                                <titlelong>E</titlelong>
                                                <type>test</type>
                                                <description>
                                                    Another sample
                                                </description>
                                                <image>includes/images/test.jpg</image>
                                                <imagelink>http://somesite.com</imagelink>
                                            </item>");

            XElement root = new XElement("root");
            root.Add(new[] { i1, i2 });

            var ts = from t in root.Elements("item").Elements("title")
                      where t.Value[0] >= 'A' && t.Value[0] <= 'E'
                      select t;

            foreach (XElement t in ts)
            {
                Console.WriteLine(t.Value);
            }

            Console.ReadLine();
        }
    }
}

提供输出

A Test
E Test2

答案 4 :(得分:0)

正则表达式

 Regex searchTerm = new Regex("^[a-eA-E]");

 var simpleListSource = (from item in doc.Descendants("item")
where searchTerm.Matches(item.Element("title").Value).Count > 0
orderby item.Element("title").Value
  select new
      {
        title = item.Element("title").Value,
        description = item.Element("description").Value,
        image = item.Element("image").Value,
        type = item.Element("type").Value,
        imagelink = item.Element("imagelink").Value

      }).ToList();

rptGetItems.DataSource = simpleListSource;
rptGetItems.DataBind();

未经测试但应该接近(正则表达式可能需要一些工作)

答案 5 :(得分:0)

为此,我想我可能会制作一个这样的方法:

public static bool IsInRange<T>(T subject, T first, T last)
{
    return IsInRange(subject, first, last, Comparer<T>.Default);
}

public static bool IsInRange<T>(T subject, T first, T last, IComparer<T> comparer)
{
    return comparer.Compare(subject, first) >= 0 && comparer.Compare(subject, last) <= 0;
}

或类似的东西。没有经过测试,但认为它应该有效:P

更新:要在您的示例中使用它,您可以执行以下操作:

var items = doc.Descendants("item")
        .Where(x => IsInRange(x.Element("title").Value[0], "A", "E")
        .OrderBy(x => x.Element("title").Value
        .Select(x => new
            {
                title = x.Element("title").Value,
                description = x.Element("description").Value,
                image = x.Element("image").Value,
                type = x.Element("type").Value,
                imagelink = x.Element("imagelink").Value
            })
        .ToList();