F# TypeProvider XMLProvider выдает System.Exception

Я пытаюсь обработать твиты Twitter с помощью поставщика типа XML, представленного в приведенном ниже коде. Код отлично работает при доступе к значениям данных твитов с помощью функций LINQ XElement, однако он завершается с ошибкой с сообщением об исключении: «Несоответствие XML: ожидается ровно один дочерний элемент title» при использовании типа, созданного XMLProvider. Я знаю, что пространства имен не даются, однако я не знаю, как они будут указаны у провайдера, если они понадобятся.

// ...

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

person Clifford Ritchie    schedule 01.04.2013    source источник
comment
Разве проблема не в том, что образец XML не соответствует реальному XML? Не могли бы вы включить сюда оба файла XML? (Или, что еще лучше, их упрощенные версии, которые все еще показывают проблему.)   -  person svick    schedule 02.04.2013


Ответы (1)


Это была ошибка в FSharp.Data, связанная с тем, что в xml xmlns="http://www.w3.org/2005/Atom" есть пространство имен по умолчанию.

В версии 1.1.3 это исправлено, но вы также можете сделать следующее в качестве обходного пути:

[<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
person Gustavo Guerra    schedule 02.04.2013
comment
Густаво определенно подчеркнул, что XmlProvider имеет серьезные недостатки. XML-файл ленты Twitter должен стать серьезной проверкой для этого провайдера. Например, при рассмотрении некоторых элементов, квалифицированных как twitter:: <feed ... > ... <entry> <twitter:metadata> <twitter:result_type>recent</twitter:result_type> </twitter:metadata>, провайдер определенно создает поля типа для этих квалифицированных элементов 'twitter'. let rt = feed.GetEntries().[0].Metadata.ResultType Однако значение ResultType недоступно. - person Clifford Ritchie; 02.04.2013
comment
Я не думаю, что сказал, что у провайдера есть серьезные недостатки, я просто сказал, что у него была ошибка. В любом случае, я отправил запрос на вытягивание, это было легко исправить (github.com/ fsharp/FSharp.Data/pull/114). Xml используется гораздо реже, чем другие поставщики в FSharp.Data, поскольку в наши дни почти все является Json, поэтому естественно, что в нем больше ошибок. - person Gustavo Guerra; 03.04.2013