Here's the sample XML
<?xml version="1.0"开发者_JS百科 encoding="utf-8" ?>
<Instructions>
<Instruction>
<Brand>Brand1</Brand>
<Text>
this is text for Brand1
</Text>
</Instruction>
<Instruction>
<Brand>Brand2</Brand>
<Text>
Brand2 text is slightly different
</Text>
</Instruction>
<Instruction>
<Brand>Brand3</Brand>
<Text>
Brand3 has boring text
</Text>
</Instruction>
<Instruction>
<Brand>Brand4</Brand>
<Text>
Brand4 had long text until the editor got hold of this file
</Text>
</Instruction>
</Instructions>
My code is this:
string WhoAmI = "Brand1";
string t =
(from Instruction in xmlDoc.Descendants("Instruction")
where (string)Instruction.Element("Brand").Value == WhoAmI
select t = Instruction.Element("Text").Value
).ToString();
//end code
t is always
System.Linq.Enumerable+WhereSelectEnumerableIterator`2 [System.Xml.Linq.XElement,System.String]
not
this is text for Brand1
What am I doing wrong?
A LINQ statement returns a sequence of values, not a single value. So calling .ToString()
on a sequence object will, ordinarily, not give you anything particularly useful.
In this case, your statement is returning a sequence with one value in it, but still a sequence. So you need to write a LINQ statement that only returns one value:
string t = (from ... select ...).First();
There's other implications to consider here, such that First()
will throw an exception if the sequence is empty. FirstOrDefault()
will return null instead.
This query will return a sequence of strings not a single string. So the .ToString() method call will be the IEnumerable ToString method.
If you are confident that your query will always only return 1 string you can use the Single() or SingleOrDefault() methods to just return the string.
string WhoAmI = "Brand1";
string t =
(from Instruction in xmlDoc.Descendants("Instruction")
where (string)Instruction.Element("Brand").Value == WhoAmI
select t = Instruction.Element("Text").Value
).SingleOrDefault();
Try replacing ToString()
with FirstOrDefault()
This will give you a collection of the Text nodes' contained text values. However, if either a Text node or a Brand node is missing this query will fail. What the code you posted was doing was not accepting a collection as a result; you were casting the collection object returned to a string which by default gives you just the name of the object.
You will need to loop through the list returned by the query to do something useful with the multiple values returned...
var results = (from e in doc.Descendants("Instruction")
where e.Descendants("Brand").First().Value == WhoAmI
select e.Descendants("Text").First().Value).ToList();
精彩评论