diff --git a/Text/Search/Sphinx.hs b/Text/Search/Sphinx.hs
--- a/Text/Search/Sphinx.hs
+++ b/Text/Search/Sphinx.hs
@@ -1,6 +1,9 @@
 -- | This is the Haskell version of the Sphinx searchd client.
 
-module Text.Search.Sphinx (Configuration (..), query, defaultConfig) where
+module Text.Search.Sphinx ( Configuration (..)
+                          , query
+                          , defaultConfig
+                          ) where
 
 import Network
 import IO hiding (bracket)
diff --git a/Text/Search/Sphinx/Configuration.hs b/Text/Search/Sphinx/Configuration.hs
--- a/Text/Search/Sphinx/Configuration.hs
+++ b/Text/Search/Sphinx/Configuration.hs
@@ -49,6 +49,7 @@
     -- | Per-field-name weights
   , fieldWeights :: [(String, Int)]
 }
+
 -- | A basic, default configuration.
 defaultConfig = Configuration {
                   port          = 3312
diff --git a/Text/Search/Sphinx/Indexable.hs b/Text/Search/Sphinx/Indexable.hs
new file mode 100644
--- /dev/null
+++ b/Text/Search/Sphinx/Indexable.hs
@@ -0,0 +1,83 @@
+module Text.Search.Sphinx.Indexable (Indexable (..), SchemaType (..), AttrType (..), Id, 
+                                     SphinxSchema (..), serialize)
+                                     where
+
+--import Text.Search.Sphinx.Types
+import Text.XML.Light
+
+-- TODO: this should really be the same as Types.Attr
+data Indexable = NumAttr Int
+               | StrAttr String
+               | Field   String
+
+data SchemaType = TField
+                | TAttribute AttrType
+
+data AttrType = AString | AInt
+
+type Id = Int
+
+class SphinxSchema a where
+  -- | Convert a value of a to a document with a document id and some attributes and fields.
+  toDocument :: a -> (Id, [(String, Indexable)])
+  -- | The first parameter should be ignored, but is used to satisfy Haskell's type system.
+  schema   :: a -> [(String, SchemaType)]
+
+serialize :: SphinxSchema a => [a] -> Element
+serialize items =
+  sphinxEl "docset" << (
+      sphinxEl "schema" << (map schemaField $ schema (head $ items))
+    : map (doc . toDocument) items
+  )
+
+doc :: (Id, [(String, Indexable)]) -> Element
+doc (id, fields) = sphinxEl "document" ! [("id", show id)] <<
+                     map docEl fields
+
+docEl :: (String, Indexable) -> Element
+docEl (name, content) = normalEl name `text` indexableEl content
+
+indexableEl (NumAttr i) = simpleText $ show i
+indexableEl (StrAttr f) = simpleText $ f
+indexableEl (Field f)   = simpleText $ f
+
+simpleText s = CData { cdVerbatim = CDataText
+                     , cdData     = s
+                     , cdLine     = Nothing
+                     }
+
+schemaField :: (String, SchemaType) -> Element
+schemaField (name, TField)       = sphinxEl "field" ! [("name", name)]
+schemaField (name, TAttribute t) = sphinxEl "attr" ! [("name", name), ("type", attrType t)]
+
+attrType :: AttrType -> String
+attrType AString = "string"
+attrType AInt    = "int"
+
+text :: Element -> CData -> Element
+text el dat = el {elContent = [Text dat]}
+
+(<<) :: Element -> [Element] -> Element
+a << b = a {elContent = map Elem b}
+
+(!) :: Element -> [(String, String)] -> Element
+el ! attrs = el {elAttribs = [Attr (unqual name) value | (name, value) <- attrs]}
+
+sphinxEl :: String -> Element
+sphinxEl name = Element { elName    = sphinxNm name
+                        , elAttribs = []
+                        , elContent = []
+                        , elLine    = Nothing
+                        }
+
+normalEl :: String -> Element
+normalEl name = Element { elName    = unqual name
+                        , elAttribs = []
+                        , elContent = []
+                        , elLine    = Nothing
+                        }
+
+sphinxNm name = blank_name { qPrefix = Just "sphinx"
+                           , qURI    = Nothing
+                           , qName   = name
+                           }
diff --git a/sphinx.cabal b/sphinx.cabal
--- a/sphinx.cabal
+++ b/sphinx.cabal
@@ -1,5 +1,5 @@
 Name:            sphinx
-Version:         0.1.1
+Version:         0.2
 Synopsis:        Haskell bindings to the Sphinx full-text searching deamon.
 Description:     Haskell bindings to the Sphinx full-text searching deamon. This
                  module is heavily inspired by the php and python client.
@@ -9,7 +9,8 @@
 Copyright:       (c) 2008 Tupil
 Author:          Tupil
 Maintainer:      Chris Eidhof <ce+sphinx@tupil.com>
-Exposed-Modules: Text.Search.Sphinx, Text.Search.Sphinx.Types, Text.Search.Sphinx.Configuration
+Exposed-Modules: Text.Search.Sphinx, Text.Search.Sphinx.Types,
+                 Text.Search.Sphinx.Configuration, Text.Search.Sphinx.Indexable
 Other-Modules:   Text.Search.Sphinx.Get, Text.Search.Sphinx.Put
 Build-Type:      Simple
-Build-Depends:   base, binary, bytestring, network, haskell98
+Build-Depends:   base, binary, bytestring, network, haskell98, xml
