I have this to find runs with text that starts with #, but I get an empty sequence back:
IEnumerable<Run> runs = doc.Descendants<Run>().
Where<Run>(r => r.Descendants<Text>().First<Text>().Text[0] == '#');
This cannot be right because the following gives me 4 results:
IEnumerable<Text> t = doc.Descendants<Text>().
Where<Text>(txt => txt.Text[0] == '#');
What do I do wrong?
Well your first snippet only gives runs whose first text descendant starts with #. Your second snippet gives all text descendants starting with #. So if you've got any runs with a non-first text descendant starting with #, that will be counted in the second snippet but not the first...
It's unclear which behaviour you actually want, but if you do want to find every run containing a text element starting with #
, just change your first snippet to:
IEnumerable<Run> runs = doc
.Descendants<Run>()
.Where<Run>(r => r.Descendants<Text>()
.Any<Text>(text => text.Text[0] == '#'));
If you're still surprised that the two snippets give you different results, you could easily check that:
foreach (var run in doc.Descendants<Run>())
{
Console.WriteLine("Run!");
foreach (var textElement in run.Descendants<Text>())
{
string text = textElement.Text;
Console.WriteLine("- {0}", text.Substring(0, Math.Min(5, text.Length)));
}
}
(I haven't used this object model for a long time, by the way - so you should also check whether there are things like nested runs.)
See more on this question at Stackoverflow