xml-enumerator 0.3.3 → 0.3.4
raw patch · 3 files changed
+64/−8 lines, 3 filesdep +failure
Dependencies added: failure
Files
- Text/XML/Enumerator/Cursor.hs +35/−2
- runtests.hs +27/−5
- xml-enumerator.cabal +2/−1
Text/XML/Enumerator/Cursor.hs view
@@ -25,8 +25,10 @@ , checkName , anyElement , element+ , laxElement , content , attribute+ , laxAttribute -- * Operators , (&|) , (&/)@@ -37,12 +39,17 @@ , ($//) , ($.//) , (>=>)+ -- * Error handling+ , force+ , forceM ) where import Control.Monad-import Data.List (foldl')+import Data.Function (on)+import Data.List (foldl') import Text.XML.Enumerator.Resolved-import qualified Data.Text as T+import qualified Control.Failure as F+import qualified Data.Text as T -- TODO: Consider [Cursor] -> [Cursor]? -- | The type of an Axis that returns a list of Cursors.@@ -259,6 +266,11 @@ element :: Name -> Axis element n = checkName (== n) +-- | Select only those elements with a loosely matching tag name. Namespace and case are ignored. XPath:+-- /A node test that is a QName is true if and only if the type of the node (see [5 Data Model]) is the principal node type and has an expanded-name equal to the expanded-name specified by the QName./+laxElement :: T.Text -> Axis+laxElement n = checkName (on (==) T.toCaseFold n . nameLocalName)+ -- | Select only text nodes, and directly give the 'Content' values. XPath: -- /The node test text() is true for any text node./ -- @@ -280,3 +292,24 @@ guard $ n == n' return v attribute _ _ = []++-- | Select attributes on the current element (or nothing if it is not an element). Namespace and case are ignored. XPath:+-- /the attribute axis contains the attributes of the context node; the axis will be empty unless the context node is an element/+-- +-- Note that this is not strictly an 'Axis', but will work with most combinators.+-- +-- The return list of the generalised axis contains as elements lists of 'Content' +-- elements, each full list representing an attribute value.+laxAttribute :: T.Text -> Cursor -> [T.Text]+laxAttribute n Cursor{node=NodeElement e} = do (n', v) <- elementAttributes e+ guard $ (on (==) T.toCaseFold) n (nameLocalName n')+ return v+laxAttribute _ _ = []++force :: F.Failure e f => e -> [a] -> f a+force e [] = F.failure e+force _ (x:_) = return x++forceM :: F.Failure e f => e -> [f a] -> f a+forceM e [] = F.failure e+forceM _ (x:_) = x
runtests.hs view
@@ -64,13 +64,18 @@ , it "has correct checkName" cursorCheckName , it "has correct anyElement" cursorAnyElement , it "has correct element" cursorElement+ , it "has correct laxElement" cursorLaxElement , it "has correct content" cursorContent , it "has correct attribute" cursorAttribute+ , it "has correct laxAttribute" cursorLaxAttribute , it "has correct &* and $* operators" cursorDeep+ , it "has correct force" cursorForce+ , it "has correct forceM" cursorForceM ] , describe "resolved" [ it "identifies unresolved entities" resolvedIdentifies , it "works for resolvable entities" resolvedAllGood+ , it "merges adjacent content nodes" resolvedMergeContent ] ] @@ -194,6 +199,7 @@ , "<bin2/>" , "<bin3/>" , "</bar3>"+ , "<Bar1 xmlns=\"http://example.com\" Attr=\"q\"/>" , "</foo>" ] @@ -210,11 +216,11 @@ name (Cu.preceding baz2) @?= ["baz1", "bar1"] name (Cu.preceding bin2) @?= ["bin1", "baz3", "baz2", "baz1", "bar2", "bar1"] cursorFollowing = do- name (Cu.following baz2) @?= ["baz3", "bar3", "bin1", "bin2", "bin3"]- name (Cu.following bar2) @?= ["bar3", "bin1", "bin2", "bin3"]+ name (Cu.following baz2) @?= ["baz3", "bar3", "bin1", "bin2", "bin3", "Bar1"]+ name (Cu.following bar2) @?= ["bar3", "bin1", "bin2", "bin3", "Bar1"] cursorPrecedingSib = name (Cu.precedingSibling baz2) @?= ["baz1"] cursorFollowingSib = name (Cu.followingSibling baz2) @?= ["baz3"]-cursorDescendant = (name $ Cu.descendant cursor) @?= T.words "bar1 bar2 baz1 baz2 baz3 bar3 bin1 bin2 bin3"+cursorDescendant = (name $ Cu.descendant cursor) @?= T.words "bar1 bar2 baz1 baz2 baz3 bar3 bin1 bin2 bin3 Bar1" cursorCheck = null (cursor $.// Cu.check (const False)) @?= True cursorPredicate = (name $ cursor $.// Cu.check Cu.descendant) @?= T.words "foo bar2 baz3 bar3" cursorCheckNode = (name $ cursor $// Cu.checkNode f) @?= T.words "bar1 bar2 bar3"@@ -224,12 +230,14 @@ where f e = "bar" `T.isPrefixOf` Res.nameLocalName (Res.elementName e) cursorCheckName = (name $ cursor $// Cu.checkName f) @?= T.words "bar1 bar2 bar3" where f n = "bar" `T.isPrefixOf` nameLocalName n-cursorAnyElement = (name $ cursor $// Cu.anyElement) @?= T.words "bar1 bar2 baz1 baz2 baz3 bar3 bin1 bin2 bin3"-cursorElement = (name $ cursor $// Cu.element "baz2") @?= ["baz2"]+cursorAnyElement = (name $ cursor $// Cu.anyElement) @?= T.words "bar1 bar2 baz1 baz2 baz3 bar3 bin1 bin2 bin3 Bar1"+cursorElement = (name $ cursor $// Cu.element "bar1") @?= ["bar1"]+cursorLaxElement = (name $ cursor $// Cu.laxElement "bar1") @?= ["bar1", "Bar1"] cursorContent = do Cu.content cursor @?= [] (cursor $.// Cu.content) @?= ["a", "b"] cursorAttribute = Cu.attribute "attr" cursor @?= ["x"]+cursorLaxAttribute = (cursor $.// Cu.laxAttribute "Attr") @?= ["x", "y", "q"] cursorDeep = do (Cu.element "foo" &/ Cu.element "bar2" &// Cu.attribute "attr") cursor @?= ["y"] (return &.// Cu.attribute "attr") cursor @?= ["x", "y"]@@ -237,6 +245,14 @@ (cursor $/ Cu.element "bar2" &// Cu.attribute "attr") @?= ["y"] (cursor $/ Cu.element "bar2" &/ Cu.element "baz2" >=> Cu.attribute "attr") @?= ["y"] null (cursor $| Cu.element "foo") @?= False+cursorForce = do+ Cu.force () [] @?= (Nothing :: Maybe Integer)+ Cu.force () [1] @?= Just 1+ Cu.force () [1,2] @?= Just 1+cursorForceM = do+ Cu.forceM () [] @?= (Nothing :: Maybe Integer)+ Cu.forceM () [Just 1, Nothing] @?= Just 1+ Cu.forceM () [Nothing, Just 1] @?= Nothing showEq :: (Show a, Show b) => Either a b -> Either a b -> Assertion showEq x y = show x @=? show y@@ -252,3 +268,9 @@ Res.toXMLDocument (Res.parseLBS_ xml P.decodeEntities) where xml = "<foo><bar/><baz/></foo>"++resolvedMergeContent =+ Res.documentRoot (Res.parseLBS_ xml P.decodeEntities) @=?+ Res.Element "foo" [] [Res.NodeContent "bar&baz"]+ where+ xml = "<foo>bar&baz</foo>"
xml-enumerator.cabal view
@@ -1,5 +1,5 @@ name: xml-enumerator-version: 0.3.3+version: 0.3.4 license: BSD3 license-file: LICENSE author: Michael Snoyman <michaels@suite-sol.com>, Aristid Breitkreuz <aristidb@googlemail.com>@@ -28,6 +28,7 @@ , blaze-builder >= 0.2 && < 0.4 , blaze-builder-enumerator >= 0.2 && < 0.3 , transformers >= 0.2 && < 0.3+ , failure >= 0.1 && < 0.2 exposed-modules: Text.XML.Enumerator.Parse Text.XML.Enumerator.Render Text.XML.Enumerator.Document