diff --git a/Data/JsonStream/Parser.hs b/Data/JsonStream/Parser.hs
--- a/Data/JsonStream/Parser.hs
+++ b/Data/JsonStream/Parser.hs
@@ -67,6 +67,9 @@
   , filterI
   , takeI
   , toList
+    -- * SAX-like parsers
+  , arrayFound
+  , objectFound
 ) where
 
 import           Control.Applicative
@@ -222,6 +225,34 @@
 arrayOf :: Parser a -> Parser a
 arrayOf valparse = array' (const valparse)
 
+-- | Generate start/end objects when an element is found, in between run a parser.
+-- The inner parser is not run if an array is not found.
+elemFound :: Element -> a -> a -> Parser a -> Parser a
+elemFound elsearch start end parser = Parser $ moreData handle
+  where
+    handle tok el _
+      | el == elsearch = Yield start (parseAndAppend (callParse parser tok))
+    handle tok _ _ = callParse ignoreVal tok
+
+    parseAndAppend (Failed err) = Failed err
+    parseAndAppend (Yield v np) = Yield v (parseAndAppend np)
+    parseAndAppend (MoreData (Parser np, ntp)) = MoreData (Parser (parseAndAppend . np), ntp)
+    parseAndAppend (Done ctx ntp) = Yield end (Done ctx ntp)
+
+-- | Generate start/end values when an array is found, in between run a parser.
+-- The inner parser is not run if an array is not found.
+objectFound :: a -> a -> Parser a -> Parser a
+objectFound = elemFound ObjectBegin
+
+-- | Generate start/end values when an object is found, in between run a parser.
+-- The inner parser is not run if an array is not found.
+--
+-- > >>> let test = "[[1,2,3],true,[],false,{\"key\":1}]" :: ByteString
+-- > >>> parseByteString (arrayOf (arrayFound 10 20 (1 .! integer))) test :: [Int]
+-- > [10,2,20,10,20]
+arrayFound :: a -> a -> Parser a -> Parser a
+arrayFound = elemFound ArrayBegin
+
 -- | Match nith item in an array.
 arrayWithIndexOf :: Int -> Parser a -> Parser a
 arrayWithIndexOf idx valparse = array' itemFn
@@ -258,7 +289,7 @@
     objcontent _ (Yield v np) = Yield v (objcontent True np)
     objcontent _ (Failed err) = Failed err
 
-    getLongKey acc len _ el ntok =
+    getLongKey acc !len _ el ntok =
       case el of
         StringEnd
           | Right key <- decodeUtf8' (BL.fromChunks $ reverse acc) ->
@@ -332,12 +363,12 @@
 longString :: Maybe Int -> Parser T.Text
 longString mbounds = Parser $ moreData (handle [] 0)
   where
-    handle acc len tok el ntok =
+    handle acc !len tok el ntok =
       case el of
         JValue (AE.String str) -> Yield str (Done "" ntok)
         StringContent str
           | (Just bounds) <- mbounds, len > bounds -- If the string exceeds bounds, discard it
-                          -> callParse (ignoreVal' 1) ntok
+                          -> callParse (ignoreStrRestThen (Parser $ Done "")) ntok
           | otherwise     -> moreData (handle (str:acc) (len + BS.length str)) ntok
         StringEnd
           | Right val <- decodeUtf8' (BL.fromChunks $ reverse acc)
@@ -462,7 +493,7 @@
     handleLongString level _ (StringContent _) ntok = moreData (handleLongString level) ntok
     handleLongString 0 _ StringEnd ntok = Done "" ntok
     handleLongString level _ StringEnd ntok = moreData (handleTok level) ntok
-    handleLongString _ _ el _ = Failed $ "Unexpected element in handleLongStr: " ++ (show el)
+    handleLongString _ _ el _ = Failed $ "Unexpected element in handleLongStr: " ++ show el
 
     handleTok :: Int -> TokenResult -> Element -> TokenResult -> ParseResult a
     handleTok 0 _ (JValue _) ntok = Done "" ntok
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,2 +1,7 @@
+# 0.3.0.4
+- Fixed bug in safestring
+- Fixed test so it doesn't depend on versions of other packages
+- Added sax-like parsers
+
 # 0.3.0.3
-Fixed wrong size of C structure in FFI that was causing a segfault.
+- Fixed wrong size of C structure in FFI that was causing a segfault.
diff --git a/json-stream.cabal b/json-stream.cabal
--- a/json-stream.cabal
+++ b/json-stream.cabal
@@ -1,5 +1,5 @@
 name:                json-stream
-version:             0.3.0.3
+version:             0.3.0.4
 synopsis:            Incremental applicative JSON parser
 description:         Easy to use JSON parser fully supporting incremental parsing.
                      Parsing grammar in applicative form.
diff --git a/test/ParserSpec.hs b/test/ParserSpec.hs
--- a/test/ParserSpec.hs
+++ b/test/ParserSpec.hs
@@ -11,6 +11,8 @@
 import Data.Text.Encoding (encodeUtf8)
 import Control.Monad (forM_)
 import Data.Text.Encoding (encodeUtf8)
+import qualified Data.Vector as Vec
+import qualified Data.HashMap.Strict as HMap
 
 import Data.JsonStream.Parser
 import Data.JsonStream.TokenParser
@@ -103,14 +105,25 @@
         msg = parseLazyByteString parser (BL.fromChunks test) :: [Int]
     msg `shouldBe` [1]
 
+  it "arrayFound generates events" $ do
+    let test = ["[[1,2,3],true,[],false,{\"key\":1}]"]
+        parser = arrayOf (arrayFound 10 20 (1 .! integer))
+        msg = parseLazyByteString parser (BL.fromChunks test) :: [Int]
+    msg `shouldBe` [10,2,20,10,20]
 
+  it "objectFound generates events" $ do
+    let test = ["[[1,2,3],true,[],false,{\"key\":1}]"]
+        parser = arrayOf (objectFound 10 20 ("key" .: integer))
+        msg = parseLazyByteString parser (BL.fromChunks test) :: [Int]
+    msg `shouldBe` [10,1,20]
+
 specEdge :: Spec
 specEdge = describe "Edge cases" $ do
   it "Correct incremental parsing 1" $ do
     let msg1 = "[ {\"test1\"  :[1,true,false,null,-3.591e+1,[12,13]], \"test2\":\"123\\r\\n\\\"\\u0041\"}]"
         pmsg = BL.fromChunks $ map BS.singleton msg1
         res = parseLazyByteString value pmsg :: [AE.Value]
-    show res `shouldBe` "[Array (fromList [Object fromList [(\"test2\",String \"123\\r\\n\\\"A\"),(\"test1\",Array (fromList [Number 1.0,Bool True,Bool False,Null,Number -35.91,Array (fromList [Number 12.0,Number 13.0])]))]])]"
+    res `shouldBe` [Array (Vec.fromList [Object $ HMap.fromList [("test2",String "123\r\n\"A"),("test1",Array (Vec.fromList [Number 1.0,Bool True,Bool False,Null,Number (-35.91),Array (Vec.fromList [Number 12.0,Number 13.0])]))]])]
 
   it "Correct incremental parsing 2" $ do
     let msg1 = "{\"test1\"  :[1,true,false,null,-3.591e+1,[12,13]], \"test2\":\"test2string\"}"
@@ -266,8 +279,15 @@
     let test1 = "[\"\", \"\", true]"
         onechar = BL.fromChunks $ map BS.singleton $ BS.unpack test1
         parser = arrayOf bool
-        res = parseByteString parser test1 :: [Bool]
+        res = parseLazyByteString parser onechar :: [Bool]
     res `shouldBe` [True]
+
+  it "Correctly parses safeString when sliced" $ do
+    let test1 = "[\"looooooooooong\", \"short\"]"
+        onechar = BL.fromChunks $ map BS.singleton $ BS.unpack test1
+        parser = arrayOf (safeString 6)
+        res = parseLazyByteString parser onechar :: [T.Text]
+    res `shouldBe` ["short"]
 
 
 -- testLexer (start:rest) = iter rest (tokenParser start)
