问题
I'm trying to process Twitter tweets using the XML type provider as represented by the code below. The code works fine when accessing tweet data values using LINQ XElement functions, however it fails with an exception saying: “XML mismatch: Expected exactly one 'title' child”, when using the type created by the XMLProvider. I know namespaces are not given, however, I don't know how they would be specified with the provider, if they're needed.
// ...
open FSharp.Net
open FSharp.Data
let ns = "http://www.w3.org/2005/Atom"
// General helpers for XML
let xelem s (el: XContainer) = el.Element(XName.Get(s, ns))
// ...
let xvalue (el: XElement) = el.Value
let twitterUri = "http://search.twitter.com/search.atom?q=Windows8&rpp=100&lang=en"
type Tweets = XmlProvider<"SampleTweets.xml", Global=false>
let feed = Tweets.Load twitterUri
// title 0 & 1 produce correct values
let title0 = feed.XElement |> xelem "title" |> xvalue
let title1 = feed.XElement |> xelem "entry" |> xelem "title" |> xvalue
// title 2 produces: "XML mismatch: Expected exactly one 'title' child"
let title2 = feed.Title
let title3 = feed.GetEntries().[0].Title
回答1:
This was a bug in FSharp.Data related to the fact that there's a default namespace in the xml xmlns="http://www.w3.org/2005/Atom"
.
Version 1.1.3 fixed this, but you could also do the following as a workaround:
[<Literal>]
let twitterUri = "http://search.twitter.com/search.atom?q=Windows8&rpp=100&lang=en"
type Tweets = XmlProvider<twitterUri>
let feedXml = (Http.Request twitterUri).Replace("xmlns=\"http://www.w3.org/2005/Atom\"", null)
let feed = Tweets.Parse feedXml
let t = feed.Title
来源:https://stackoverflow.com/questions/15753005/f-typeprovider-xmlprovider-gives-system-exception