问题
I am creating a List of structs using linq to xml.
The linq path does not find the concept elements. I have tried various formulations of this and before I give up and use xpath I am hoping someone can show me the linq way. thanks
Here is the xml
<response xmlns="http://www.domain.com/api">
<about>
<requestId>E9B73CA1F16A670C966BE2BABD3B2B22</requestId>
<docId>09E167D994E00B0F511781C40B85AEC3</docId>
<systemType>concept</systemType>
<configId>odp_2007_l1_1.7k</configId>
<contentType>text/plain</contentType>
<contentDigest>09E167D994E00B0F511781C40B85AEC3</contentDigest>
<requestDate>2011-10-18T09:51:28+00:00</requestDate>
<systemVersion>2.1</systemVersion>
</about>
<conceptExtractor>
<conceptExtractorResponse>
<concepts>
<concept weight="0.010466908" label="hell"/>
</concepts>
</conceptExtractorResponse>
</conceptExtractor>
</response>
here is what I have
public struct conceptweight
{
public string concept { get; set; }
public string weight { get; set; }
}
List<conceptweight> list = (from c
in d.Descendants("response")
.Descendants("conceptExtractor")
.Descendants("conceptExtractorResponse")
.Descendants("concepts")
select new conceptweight()
{
concept = c.Attribute("label").Value,
weight = c.Attribute("weight").Value
}).ToList();
回答1:
You've forgotten the namespace, which is defaulted in the root element. Try this:
// Note: names changed to follow conventions, and now a class
// rather than a struct. Mutable structs are evil.
public class ConceptWeight
{
public string Concept { get; set; }
// Type changed to reflect the natural data type
public double Weight { get; set; }
}
XNamespace ns = "http://www.domain.com/api";
// No need to traverse the path all the way, unless there are other "concepts"
// elements you want to ignore. Note the use of ns here.
var list = d.Descendants(ns + "concepts")
.Select(c => new ConceptWeight
{
Concept = (string) c.Attribute("label"),
Weight = (double) c.Attribute("weight"),
})
.ToList();
I haven't used a query expression here as it wasn't adding any value - you were only doing from x in y select z
, which is more simply expressed via the Select
extension method.
回答2:
XNamespace n = "http://www.domain.com/api";
List<conceptweight> list = (from c in d.Elements(n + "response").Elements(n + "conceptExtractor").Elements(n + "conceptExtractorResponse").Elements(n + "concepts").Elements(n + "concept")
select new conceptweight
{
concept = c.Attribute("label").Value,
weight = c.Attribute("weight").Value
}).ToList();
You forgot the namespace and the last element (concept
). Ah and you don't need the ()
brackets in new conceptweight
if you do the inline initialization. Ah and Descendants
will traverse all the "levels" of elements. If you want to traverse it "manually", use Elements
.
来源:https://stackoverflow.com/questions/7806604/linq-to-xml-not-getting-a-result