score:1

Accepted answer

I have figured it out! Although I don't know why the Xlinq approach doesn't work... here is the code that worked for me instead of the query:

    public XElement filter(int min = 0, int max = int.MaxValue)
    {            
        XElement filtered = new XElement("Stock");
        foreach (XElement product in xmlFile.Elements("Product"))
        {
            if ((int)product.Element("Price") >= min &&
                (int)product.Element("Price") <= max)
                    filtered.Add(product);
        }
        return filtered;
    }

that would be great if someone gives me an explain. thanks for reading

score:2

If you have "empty" or "not existing" price elements it will break

Try this:

public static IEnumerable<XElement> Filter(int min = 0, int max = int.MaxValue)
{
    Func<XElement, int?> parse = p => {
        var element = p.Element("Price");

        if (element == null) {
            return null;
        }

        int value;

        if (!Int32.TryParse(element.Value, out value)) {
            return null;
        }

        return value;
    };

    IEnumerable<XElement> selected = (
        from x in xmlFile.Elements("Product")
        let value = parse(x)
        where value >= min &&
            value <= max
        select x);

    return arr;
}

score:0

You have two issues:

  1. When you hovered over the WhereEnumerableIterator and saw .Current was null, everything was working normally. This is deferred execution at work. Some LINQ queries (this applies to XLinq too) do not execute until you enumerate them, hence .Current will be null until you use it! When you used foreach in your answer it enumerated the iterator and produced a value.

  2. Your initial code did not work as it returned an enumeration of XML without a root element, and it appears whatever your calling code is it required it to have a root. Your answer wraps the data in a <Stock> element. You can use your original code like so:

    public XElement Filter(int min = 0, int max = int.MaxValue)
    {
        var selected = (
            from x in xmlFile.Elements("Product")
            where (int)x.Element("Price") >= min &&
                  (int)x.Element("Price") <= max
            select x);
    
        return new XElement("Stock", selected);
    }
    

Related Articles