diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,7 @@
+## 1.3.1
+
+* Add functions to ignore subtrees & result-streaming (yield) parsers [#58](https://github.com/snoyberg/xml/pull/58)
+
 ## 1.3.0
 
 * Drop system-filepath
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,25 +1,20 @@
-The following license covers this documentation, and the source code, except
-where otherwise indicated.
-
 Copyright 2010, Suite Solutions. All rights reserved.
 
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice, this
-  list of conditions and the following disclaimer.
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
 
-* Redistributions in binary form must reproduce the above copyright notice,
-  this list of conditions and the following disclaimer in the documentation
-  and/or other materials provided with the distribution.
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
 
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
-OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/Text/XML/Stream/Parse.hs b/Text/XML/Stream/Parse.hs
--- a/Text/XML/Stream/Parse.hs
+++ b/Text/XML/Stream/Parse.hs
@@ -43,6 +43,35 @@
 --
 -- > [Person {age = 25, name = "Michael"},Person {age = 2, name = "Eliezer"}]
 --
+-- This module also supports streaming results using 'yield'.
+-- This allows parser results to be processed using conduits
+-- while a particular parser (e.g. 'many') is still running.
+-- Without using streaming results, you have to wait until the parser finished
+-- before you can process the result list. Large XML files might be easier
+-- to process by using streaming results.
+-- See http://stackoverflow.com/q/21367423/2597135 for a related discussion.
+--
+-- > {-# LANGUAGE OverloadedStrings #-}
+-- > import Control.Monad.Trans.Resource
+-- > import Data.Conduit
+-- > import Data.Text (Text, unpack)
+-- > import Text.XML.Stream.Parse
+-- > import Text.XML (Name)
+-- > import Control.Monad.Trans.Class (lift)
+-- > import Control.Monad (void)
+-- > import qualified Data.Conduit.List as CL
+-- >
+-- > data Person = Person Int Text deriving Show
+-- >
+-- > parsePerson = tagName "person" (requireAttr "age") $ \age -> do
+-- >     name <- content
+-- >     return $ Person (read $ unpack age) name
+-- >
+-- > parsePeople = void $ tagNoAttr "people" $ manyYield parsePerson
+-- >
+-- > main = runResourceT $
+-- >     parseFile def "people.xml" $$ parsePeople =$ CL.mapM_ (lift . print)
+--
 -- Previous versions of this module contained a number of more sophisticated
 -- functions written by Aristid Breitkreuz and Dmitry Olshansky. To keep this
 -- package simpler, those functions are being moved to a separate package. This
@@ -71,8 +100,20 @@
     , tagPredicate
     , tagName
     , tagNoAttr
+    , tagIgnoreAttrs
+    , tagPredicateIgnoreAttrs
     , content
     , contentMaybe
+      -- * Ignoring tags/trees
+    , ignoreTag
+    , ignoreTagName
+    , ignoreAnyTagName
+    , ignoreAllTags
+    , ignoreTree
+    , ignoreTreeName
+    , ignoreAnyTreeName
+    , ignoreAllTrees
+    , ignoreAllTreesContent
       -- * Attribute parsing
     , AttrParser
     , attr
@@ -85,7 +126,13 @@
     , orE
     , choose
     , many
+    , manyIgnore
+    , many'
     , force
+      -- * Streaming combinators
+    , manyYield
+    , manyIgnoreYield
+    , manyYield'
       -- * Exceptions
     , XmlException (..)
       -- * Other types
@@ -367,7 +414,7 @@
         char' '-'
         char' '-'
         c <- T.pack <$> manyTill anyChar (string "-->") -- FIXME use takeWhile instead
-        return $ TokenComment c
+        return $ TokenComment c 
     parseCdata = do
         _ <- string "[CDATA["
         t <- T.pack <$> manyTill anyChar (string "]]>") -- FIXME use takeWhile instead
@@ -653,6 +700,79 @@
           -> CI.ConduitM Event o m (Maybe a)
 tagNoAttr name f = tagName name (return ()) $ const f
 
+
+-- | A further simplified tag parser, which ignores all attributes, if any exist
+tagIgnoreAttrs :: MonadThrow m
+               => Name -- ^ The name this parser matches to
+               -> CI.ConduitM Event o m a -- ^ Handler function to handle the children of the matched tag
+               -> CI.ConduitM Event o m (Maybe a)
+tagIgnoreAttrs name f = tagName name ignoreAttrs $ const f
+
+-- | A further simplified tag parser, which ignores all attributes, if any exist
+tagPredicateIgnoreAttrs :: MonadThrow m
+                        => (Name -> Bool) -- ^ The name predicate this parser matches to
+                        -> CI.ConduitM Event o m a -- ^ Handler function to handle the children of the matched tag
+                        -> CI.ConduitM Event o m (Maybe a)
+tagPredicateIgnoreAttrs namePred f = tagPredicate namePred ignoreAttrs $ const f
+
+-- | Ignore an empty tag and all of its attributes by predicate.
+--   This does not ignore the tag recursively
+--   (i.e. it assumes there are no child elements).
+--   This functions returns 'Just' if the tag matched.
+ignoreTag :: MonadThrow m
+          => (Name -> Bool) -- ^ The predicate name to match to
+          -> ConduitM Event o m (Maybe ())
+ignoreTag namePred = tagPredicateIgnoreAttrs namePred (return ())
+
+-- | Like 'ignoreTag', but matches an exact name
+ignoreTagName :: MonadThrow m
+              => Name -- ^ The name to match to
+              -> ConduitM Event o m (Maybe ())
+ignoreTagName name = ignoreTag (== name)
+
+-- | Like 'ignoreTagName', but matches any name from a list of names.
+ignoreAnyTagName :: MonadThrow m
+                 => [Name] -- ^ The name to match to
+                 -> ConduitM Event o m (Maybe ())
+ignoreAnyTagName names = ignoreTag (`elem` names)
+
+-- | Like 'ignoreTag', but matches all tag name.
+--
+--   > ignoreAllTags = ignoreTag (const True)
+ignoreAllTags :: MonadThrow m => ConduitM Event o m (Maybe ())
+ignoreAllTags = ignoreTag $ const True
+
+-- | Ignore an empty tag, its attributes and its children subtree recursively.
+--   Both content and text events are ignored.
+--   This functions returns 'Just' if the tag matched.
+ignoreTree :: MonadThrow m
+          => (Name -> Bool) -- ^ The predicate name to match to
+          -> ConduitM Event o m (Maybe ())
+ignoreTree namePred =
+    tagPredicateIgnoreAttrs namePred (const () <$> many ignoreAllTreesContent)
+
+-- | Like 'ignoreTagName', but also ignores non-empty tabs
+ignoreTreeName :: MonadThrow m
+               => Name
+               -> ConduitM Event o m (Maybe ())
+ignoreTreeName name = ignoreTree (== name)
+
+-- | Like 'ignoreTagName', but matches any name from a list of names.
+ignoreAnyTreeName :: MonadThrow m
+                 => [Name] -- ^ The name to match to
+                 -> ConduitM Event o m (Maybe ())
+ignoreAnyTreeName names = ignoreTree (`elem` names)
+
+-- | Like 'ignoreAllTags', but ignores entire subtrees.
+--
+--   > ignoreAllTrees = ignoreTree (const True)
+ignoreAllTrees :: MonadThrow m => ConduitM Event o m (Maybe ())
+ignoreAllTrees = ignoreTree $ const True
+
+-- | Like 'ignoreAllTrees', but also ignores all content events
+ignoreAllTreesContent :: MonadThrow m => ConduitM Event o m (Maybe ())
+ignoreAllTreesContent = (void <$> contentMaybe) `orE` ignoreAllTrees
+
 -- | Get the value of the first parser which returns 'Just'. If no parsers
 -- succeed (i.e., return @Just@), this function returns 'Nothing'.
 --
@@ -786,6 +906,57 @@
     go front = i >>=
         maybe (return $ front [])
               (\y -> go $ front . (:) y)
+
+-- | Keep parsing elements as long as the parser returns 'Just'
+--   or the ignore parser returns 'Just'.
+manyIgnore :: Monad m
+           => Consumer Event m (Maybe a)
+           -> Consumer Event m (Maybe ())
+           -> Consumer Event m [a]
+manyIgnore i ignored =
+    go id
+  where
+    go front = i >>=
+        maybe (onFail front) (\y -> go $ front . (:) y)
+    -- onFail is called if the main parser fails
+    onFail front =
+        ignored >>= maybe (return $ front []) (const $ go front)
+
+-- | Like @many@, but any tags and content the consumer doesn't match on
+--   are silently ignored.
+many' :: MonadThrow m
+           => Consumer Event m (Maybe a)
+           -> Consumer Event m [a]
+many' consumer = manyIgnore consumer ignoreAllTreesContent
+
+-- | Like 'many', but uses 'yield' so the result list can be streamed
+--   to downstream conduits without waiting for 'manyYield' to finished
+manyYield :: Monad m
+          => ConduitM a b m (Maybe b)
+          -> Conduit a m b
+manyYield consumer =
+    loop
+  where
+    loop = consumer >>= maybe (return ()) (\x -> yield x >> loop)
+
+-- | Like @manyIgnore@, but uses 'yield' so the result list can be streamed
+--   to downstream conduits without waiting for 'manyYield' to finished
+manyIgnoreYield :: MonadThrow m
+                => ConduitM Event b m (Maybe b) -- ^ Consuming parser that generates the result stream
+                -> Consumer Event m (Maybe ()) -- ^ Ignore parser that consumes elements to be ignored
+                -> Conduit Event m b
+manyIgnoreYield consumer ignoreParser =
+    loop
+  where
+    loop = consumer >>= maybe onFail (\x -> yield x >> loop)
+    onFail = ignoreParser >>= maybe (return ()) (const loop)
+
+-- | Like @many'@, but uses 'yield' so the result list can be streamed
+--   to downstream conduits without waiting for 'manyYield' to finished
+manyYield' :: MonadThrow m
+           => ConduitM Event b m (Maybe b)
+           -> Conduit Event m b
+manyYield' consumer = manyIgnoreYield consumer ignoreAllTreesContent
 
 type DecodeEntities = Text -> Content
 
diff --git a/test/main.hs b/test/main.hs
--- a/test/main.hs
+++ b/test/main.hs
@@ -20,6 +20,7 @@
 import Text.XML.Cursor ((&/), (&//), (&.//), ($|), ($/), ($//), ($.//))
 import Data.Text(Text)
 import Control.Monad
+import Control.Applicative ((<$>))
 import Control.Monad.Trans.Class (lift)
 import qualified Data.Text as T
 import qualified Data.Set as Set
@@ -39,6 +40,8 @@
         it "has valid parser combinators" combinators
         it "has working choose function" testChoose
         it "has working many function" testMany
+        it "has working many' function" testMany'
+        it "has working manyYield function" testManyYield
         it "has working orE" testOrE
         it "is idempotent to parse and pretty render a document" documentParsePrettyRender
         it "ignores the BOM" parseIgnoreBOM
@@ -166,6 +169,28 @@
         , "</hello>"
         ]
 
+testManyYield :: Assertion
+testManyYield = do
+    -- Basically the same as testMany, but consume the streamed result
+    result <- C.runResourceT $
+        P.parseLBS def input C.$$ helloParser
+        C.$= CL.consume
+    length result @?= 5
+  where
+    helloParser = void $ P.tagNoAttr "hello" $ P.manyYield successParser
+    successParser = P.tagNoAttr "success" $ return ()
+    input = L.concat
+        [ "<?xml version='1.0'?>"
+        , "<!DOCTYPE foo []>\n"
+        , "<hello>"
+        , "<success/>"
+        , "<success/>"
+        , "<success/>"
+        , "<success/>"
+        , "<success/>"
+        , "</hello>"
+        ]
+
 testMany :: Assertion
 testMany = C.runResourceT $ P.parseLBS def input C.$$ do
     P.force "need hello" $ P.tagNoAttr "hello" $ do
@@ -180,6 +205,26 @@
         , "<success/>"
         , "<success/>"
         , "<success/>"
+        , "<success/>"
+        , "</hello>"
+        ]
+
+testMany' :: Assertion
+testMany' = C.runResourceT $ P.parseLBS def input C.$$ do
+    P.force "need hello" $ P.tagNoAttr "hello" $ do
+        x <- P.many' $ P.tagNoAttr "success" $ return ()
+        liftIO $ length x @?= 5
+  where
+    input = L.concat
+        [ "<?xml version='1.0'?>"
+        , "<!DOCTYPE foo []>\n"
+        , "<hello>"
+        , "<success/>"
+        , "<success/>"
+        , "<success/>"
+        , "<foobar/>"
+        , "<success/>"
+        , "<foo><bar attr=\"1\">some content</bar></foo>"
         , "<success/>"
         , "</hello>"
         ]
diff --git a/xml-conduit.cabal b/xml-conduit.cabal
--- a/xml-conduit.cabal
+++ b/xml-conduit.cabal
@@ -1,6 +1,6 @@
 name:            xml-conduit
-version:         1.3.0
-license:         BSD3
+version:         1.3.1
+license:         MIT
 license-file:    LICENSE
 author:          Michael Snoyman <michael@snoyman.com>, Aristid Breitkreuz <aristidb@googlemail.com>
 maintainer:      Michael Snoyman <michael@snoyman.com>
