Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

We use libraries to handle XML itself, and convert it to objects, so that we get compile errors when schemas change and know what code has to change to match it.

If we were DOM-walking or similar then I can totally see where functional code would come in useful (LINQ being a halfway house in that respect).



In F# it's super easy to deal with the XML stream itself. Define all the records for the stuff you want to deal with and iterate over the stream with a match statement that invokes read(). You can further abstract the code by making it work with a map that maps element names to parsing functions.

eg.

  type BookXml =
    | Author of { Name: string }
    | Book of { Author: Author ; Title : string }
    | Document of Seq<BookXML>

  let readAuthor (xml:XmlTextReader) : BookXml =
    { Name: xml.ReadContentAsString() }

  let readBook (xml:XmlTextReader) : BookXml =
     { Author = readAuthor(xml); Title = xml.ReadContentAsString() }
  
  let parse xml = 
    match (xml.Read(),xml.Name) with
    | false,_ -> bookList
    | _, "Author" -> (readAuthor xml)
    | _, "Book" ->  (readBook xml))

  let rec readDoc (xml:XmlTextReader) (bookList:BookXML) =
    seq {
      yield! readDoc xml (parse xml)
    }
It's been a while since I've written F# code to operate on XmlStreams but it's definitely possible and once you get the hang of it, very simple, and you don't have to store the whole tree in memory as you do with the conversion to "objects".




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: