xml-types 0.1.4 → 0.3.8
raw patch · 5 files changed
Files
- COPYING +22/−0
- Data/XML/Types.hs +0/−229
- lib/Data/XML/Types.hs +395/−0
- license.txt +0/−22
- xml-types.cabal +29/−8
+ COPYING view
@@ -0,0 +1,22 @@+Copyright (c) 2010 John Millikin++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:++The above copyright notice and this permission notice shall be+included in all copies or substantial portions of the Software.++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.
− Data/XML/Types.hs
@@ -1,229 +0,0 @@--- Copyright (c) 2010 John Millikin------ 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:------ The above copyright notice and this permission notice shall be--- included in all copies or substantial portions of the Software.------ 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.--module Data.XML.Types- ( -- * Types- -- ** Document prologue- Document (..)- , Prologue (..)- , Instruction (..)- , Miscellaneous (..)- - -- ** Document body- , Node (..)- , Element (..)- , Attribute (..)- , Content (..)- , Name (..)- , Named (..)- - -- ** Doctypes- , Doctype (..)- , ExternalID (..)- , InternalSubset- - -- ** Incremental processing- , Event (..)- - -- * Predicates- , isElement- , isInstruction- , isContent- , isComment- , isNamed- - -- * Filters- , nodeChildren- , elementChildren- , elementContent- , hasAttribute- , position- ) where-import Control.Monad ((>=>))-import Data.Text.Lazy (Text)-import qualified Data.Text.Lazy as T-import Data.String (IsString, fromString)-import Data.Function (on)--data Document = Document- { documentPrologue :: Prologue- , documentRoot :: Element- , documentEpilogue :: [Miscellaneous]- }- deriving (Show, Eq)--data Prologue = Prologue- { prologueBefore :: [Miscellaneous]- , prologueDoctype :: Maybe Doctype- , prologueAfter :: [Miscellaneous]- }- deriving (Show, Eq)--data Instruction = Instruction- { instructionTarget :: Text- , instructionData :: Text- }- deriving (Show, Eq, Ord)--data Miscellaneous- = MiscInstruction Instruction- | MiscComment Text- deriving (Show, Eq)--data Node- = NodeElement Element- | NodeInstruction Instruction- | NodeContent Content- | NodeComment Text- deriving (Show, Eq)--data Element = Element- { elementName :: Name- , elementAttributes :: [Attribute]- , elementNodes :: [Node]- }- deriving (Show, Eq)--data Attribute = Attribute- { attributeName :: Name- , attributeContent :: [Content]- }- deriving (Show, Eq)--data Content- = ContentText Text- | ContentEntity Text- deriving (Show, Eq)--data Name = Name- { nameLocalName :: Text- , nameNamespace :: Maybe Text- , namePrefix :: Maybe Text- }- deriving (Show)---- | Ignores prefixes-instance Eq Name where- (==) = (==) `on` (\x -> (nameNamespace x, nameLocalName x))---- | Ignores prefixes------ Since 0.1.3-instance Ord Name where- compare = compare `on` (\x -> (nameNamespace x, nameLocalName x))---- | Supports Clark notation; see <http://www.jclark.com/xml/xmlns.htm> and--- <http://infohost.nmt.edu/tcc/help/pubs/pylxml/etree-QName.html>------ Since 0.1.2-instance IsString Name where- fromString "" = Name T.empty Nothing Nothing- fromString full@('{':rest) = case break (== '}') rest of- (_, "") -> error ("Invalid Clark notation: " ++ show full)- (ns, local) -> Name (T.pack (drop 1 local)) (Just (T.pack ns)) Nothing- fromString local = Name (T.pack local) Nothing Nothing--class Named a where- getName :: a -> Name--instance Named Element where- getName = elementName--instance Named Attribute where- getName = attributeName--data Doctype = Doctype- { doctypeName :: Text- , doctypeExternalID :: Maybe ExternalID- , doctypeInternalSubsets :: [InternalSubset]- }- deriving (Show, Eq)---- | Since 0.1.3-instance Ord Doctype where- compare = compare `on` (\x -> (doctypeName x, doctypeExternalID x))--data ExternalID- = SystemID Text- | PublicID Text Text- deriving (Show, Eq, Ord)--data InternalSubset = InternalSubset- -- TODO- deriving (Show, Eq)---- | Some XML processing tools are incremental, and work in terms of events--- rather than node trees. Defining the event type here, even though it won't--- be useful to most users, allows these packages to interoperate more easily.------ Since: 0.1.1-data Event- = EventBeginDocument- | EventEndDocument- | EventInstruction Instruction- | EventDoctype Doctype- | EventBeginElement Name [Attribute]- | EventEndElement Name- | EventContent Content- | EventComment Text- deriving (Show, Eq)--isElement :: Node -> [Element]-isElement (NodeElement e) = [e]-isElement _ = []--isInstruction :: Node -> [Instruction]-isInstruction (NodeInstruction i) = [i]-isInstruction _ = []--isContent :: Node -> [Content]-isContent (NodeContent c) = [c]-isContent _ = []--isComment :: Node -> [Text]-isComment (NodeComment t) = [t]-isComment _ = []--isNamed :: Named a => Name -> a -> [a]-isNamed n x = [x | getName x == n]--elementChildren :: Element -> [Element]-elementChildren = elementNodes >=> isElement---- | Since 0.1.4-elementContent :: Element -> [Content]-elementContent = elementNodes >=> isContent--nodeChildren :: Node -> [Node]-nodeChildren = isElement >=> elementNodes--position :: Integer -> (a -> [b]) -> a -> [b]-position n f e = safeHead n (f e)--safeHead :: Integer -> [a] -> [a]-safeHead _ [] = []-safeHead 0 (x:_) = [x]-safeHead n (_:xs) = safeHead (n - 1) xs--hasAttribute :: (Attribute -> [Attribute]) -> Element -> [Element]-hasAttribute f e = [e | not $ null (elementAttributes e >>= f)]
+ lib/Data/XML/Types.hs view
@@ -0,0 +1,395 @@+{-# LANGUAGE CPP #-}+#if __GLASGOW_HASKELL__+{-# LANGUAGE DeriveDataTypeable #-}+#if MIN_VERSION_base(4,4,0)+{-# LANGUAGE DeriveGeneric #-}+#endif+#endif++-- |+-- Module: Data.XML.Types+-- Copyright: 2010-2011 John Millikin+-- License: MIT+--+-- Basic types for representing XML.+--+-- The idea is to have a full set of appropriate types, which various XML+-- libraries can share. Instead of having equivalent-but-incompatible types+-- for every binding, parser, or client, they all share the same types can+-- can thus interoperate easily.+--+-- This library contains complete types for most parts of an XML document,+-- including the prologue, node tree, and doctype. Some basic combinators+-- are included for common tasks, including traversing the node tree and+-- filtering children.+--+module Data.XML.Types+ ( -- * Types++ -- ** Document prologue+ Document (..)+ , Prologue (..)+ , Instruction (..)+ , Miscellaneous (..)++ -- ** Document body+ , Node (..)+ , Element (..)+ , Content (..)+ , Name (..)++ -- ** Doctypes+ , Doctype (..)+ , ExternalID (..)++ -- ** Incremental processing+ , Event (..)++ -- * Combinators++ -- ** Filters+ , isElement+ , isInstruction+ , isContent+ , isComment+ , isNamed++ -- ** Element traversal+ , elementChildren+ , elementContent+ , elementText++ -- ** Node traversal+ , nodeChildren+ , nodeContent+ , nodeText++ -- ** Attributes+ , hasAttribute+ , hasAttributeText+ , attributeContent+ , attributeText+ ) where++import Control.Monad ((>=>))+import Data.Function (on)+import Data.Maybe (isJust)+import Data.String (IsString, fromString)+import Data.Text (Text)+import qualified Data.Text as T+import Control.DeepSeq (NFData(rnf))++#if __GLASGOW_HASKELL__+import Data.Typeable (Typeable)+import Data.Data (Data)++#if MIN_VERSION_base(4,4,0)+import GHC.Generics (Generic)+#endif+#endif++data Document = Document+ { documentPrologue :: Prologue+ , documentRoot :: Element+ , documentEpilogue :: [Miscellaneous]+ }+ deriving (Eq, Ord, Show+#if __GLASGOW_HASKELL__+ , Data, Typeable+#if MIN_VERSION_base(4,4,0)+ , Generic+#endif+#endif+ )++instance NFData Document where+ rnf (Document a b c) = rnf a `seq` rnf b `seq` rnf c `seq` ()++data Prologue = Prologue+ { prologueBefore :: [Miscellaneous]+ , prologueDoctype :: Maybe Doctype+ , prologueAfter :: [Miscellaneous]+ }+ deriving (Eq, Ord, Show+#if __GLASGOW_HASKELL__+ , Data, Typeable+#if MIN_VERSION_base(4,4,0)+ , Generic+#endif+#endif+ )++instance NFData Prologue where+ rnf (Prologue a b c) = rnf a `seq` rnf b `seq` rnf c `seq` ()++data Instruction = Instruction+ { instructionTarget :: Text+ , instructionData :: Text+ }+ deriving (Eq, Ord, Show+#if __GLASGOW_HASKELL__+ , Data, Typeable+#if MIN_VERSION_base(4,4,0)+ , Generic+#endif+#endif+ )++instance NFData Instruction where+ rnf (Instruction a b) = rnf a `seq` rnf b `seq` ()++data Miscellaneous+ = MiscInstruction Instruction+ | MiscComment Text+ deriving (Eq, Ord, Show+#if __GLASGOW_HASKELL__+ , Data, Typeable+#if MIN_VERSION_base(4,4,0)+ , Generic+#endif+#endif+ )++instance NFData Miscellaneous where+ rnf (MiscInstruction a) = rnf a `seq` ()+ rnf (MiscComment a) = rnf a `seq` ()++data Node+ = NodeElement Element+ | NodeInstruction Instruction+ | NodeContent Content+ | NodeComment Text+ deriving (Eq, Ord, Show+#if __GLASGOW_HASKELL__+ , Data, Typeable+#if MIN_VERSION_base(4,4,0)+ , Generic+#endif+#endif+ )++instance NFData Node where+ rnf (NodeElement a) = rnf a `seq` ()+ rnf (NodeInstruction a) = rnf a `seq` ()+ rnf (NodeContent a) = rnf a `seq` ()+ rnf (NodeComment a) = rnf a `seq` ()++instance IsString Node where+ fromString = NodeContent . fromString++data Element = Element+ { elementName :: Name+ , elementAttributes :: [(Name, [Content])]+ , elementNodes :: [Node]+ }+ deriving (Eq, Ord, Show+#if __GLASGOW_HASKELL__+ , Data, Typeable+#if MIN_VERSION_base(4,4,0)+ , Generic+#endif+#endif+ )++instance NFData Element where+ rnf (Element a b c) = rnf a `seq` rnf b `seq` rnf c `seq` ()++data Content+ = ContentText Text+ | ContentEntity Text -- ^ For pass-through parsing+ deriving (Eq, Ord, Show+#if __GLASGOW_HASKELL__+ , Data, Typeable+#if MIN_VERSION_base(4,4,0)+ , Generic+#endif+#endif+ )++instance NFData Content where+ rnf (ContentText a) = rnf a `seq` ()+ rnf (ContentEntity a) = rnf a `seq` ()++instance IsString Content where+ fromString = ContentText . fromString++-- | A fully qualified name.+--+-- Prefixes are not semantically important; they are included only to+-- simplify pass-through parsing. When comparing names with 'Eq' or 'Ord'+-- methods, prefixes are ignored.+--+-- The @IsString@ instance supports Clark notation; see+-- <http://www.jclark.com/xml/xmlns.htm> and+-- <http://infohost.nmt.edu/tcc/help/pubs/pylxml/etree-QName.html>. Use+-- the @OverloadedStrings@ language extension for very simple @Name@+-- construction:+--+-- > myname :: Name+-- > myname = "{http://example.com/ns/my-namespace}my-name"+--+data Name = Name+ { nameLocalName :: Text+ , nameNamespace :: Maybe Text+ , namePrefix :: Maybe Text+ }+ deriving (Show+#if __GLASGOW_HASKELL__+ , Data, Typeable+#if MIN_VERSION_base(4,4,0)+ , Generic+#endif+#endif+ )++instance Eq Name where+ (==) = (==) `on` (\x -> (nameNamespace x, nameLocalName x))++instance Ord Name where+ compare = compare `on` (\x -> (nameNamespace x, nameLocalName x))++instance IsString Name where+ fromString "" = Name T.empty Nothing Nothing+ fromString full@('{':rest) = case break (== '}') rest of+ (_, "") -> error ("Invalid Clark notation: " ++ show full)+ (ns, local) -> Name (T.pack (drop 1 local)) (Just (T.pack ns)) Nothing+ fromString local = Name (T.pack local) Nothing Nothing++instance NFData Name where+ rnf (Name a b c) = rnf a `seq` rnf b `seq` rnf c `seq` ()++-- | Note: due to the incredible complexity of DTDs, this type only supports+-- external subsets. I've tried adding internal subset types, but they+-- quickly gain more code than the rest of this module put together.+--+-- It is possible that some future version of this library might support+-- internal subsets, but I am no longer actively working on adding them.+data Doctype = Doctype+ { doctypeName :: Text+ , doctypeID :: Maybe ExternalID+ }+ deriving (Eq, Ord, Show+#if __GLASGOW_HASKELL__+ , Data, Typeable+#if MIN_VERSION_base(4,4,0)+ , Generic+#endif+#endif+ )++instance NFData Doctype where+ rnf (Doctype a b) = rnf a `seq` rnf b `seq` ()++data ExternalID+ = SystemID Text+ | PublicID Text Text+ deriving (Eq, Ord, Show+#if __GLASGOW_HASKELL__+ , Data, Typeable+#if MIN_VERSION_base(4,4,0)+ , Generic+#endif+#endif+ )++instance NFData ExternalID where+ rnf (SystemID a) = rnf a `seq` ()+ rnf (PublicID a b) = rnf a `seq` rnf b `seq` ()++-- | Some XML processing tools are incremental, and work in terms of events+-- rather than node trees. The 'Event' type allows a document to be fully+-- specified as a sequence of events.+--+-- Event-based XML libraries include:+--+-- * <http://hackage.haskell.org/package/xml-enumerator>+--+-- * <http://hackage.haskell.org/package/libxml-enumerator>+--+-- * <http://hackage.haskell.org/package/expat-enumerator>+--+data Event+ = EventBeginDocument+ | EventEndDocument+ | EventBeginDoctype Text (Maybe ExternalID)+ | EventEndDoctype+ | EventInstruction Instruction+ | EventBeginElement Name [(Name, [Content])]+ | EventEndElement Name+ | EventContent Content+ | EventComment Text+ | EventCDATA Text+ deriving (Eq, Ord, Show+#if __GLASGOW_HASKELL__+ , Data, Typeable+#if MIN_VERSION_base(4,4,0)+ , Generic+#endif+#endif+ )++instance NFData Event where+ rnf (EventBeginDoctype a b) = rnf a `seq` rnf b `seq` ()+ rnf (EventInstruction a) = rnf a `seq` ()+ rnf (EventBeginElement a b) = rnf a `seq` rnf b `seq` ()+ rnf (EventEndElement a) = rnf a `seq` ()+ rnf (EventContent a) = rnf a `seq` ()+ rnf (EventComment a) = rnf a `seq` ()+ rnf (EventCDATA a) = rnf a `seq` ()+ rnf _ = ()++isElement :: Node -> [Element]+isElement (NodeElement e) = [e]+isElement _ = []++isInstruction :: Node -> [Instruction]+isInstruction (NodeInstruction i) = [i]+isInstruction _ = []++isContent :: Node -> [Content]+isContent (NodeContent c) = [c]+isContent _ = []++isComment :: Node -> [Text]+isComment (NodeComment t) = [t]+isComment _ = []++isNamed :: Name -> Element -> [Element]+isNamed n e = [e | elementName e == n]++elementChildren :: Element -> [Element]+elementChildren = elementNodes >=> isElement++elementContent :: Element -> [Content]+elementContent = elementNodes >=> isContent++elementText :: Element -> [Text]+elementText = elementContent >=> contentText++nodeChildren :: Node -> [Node]+nodeChildren = isElement >=> elementNodes++nodeContent :: Node -> [Content]+nodeContent = nodeChildren >=> isContent++nodeText :: Node -> [Text]+nodeText = nodeContent >=> contentText++hasAttribute :: Name -> Element -> [Element]+hasAttribute name e = [e | isJust (attributeContent name e)]++hasAttributeText :: Name -> (Text -> Bool) -> Element -> [Element]+hasAttributeText name p e = [e | maybe False p (attributeText name e)]++attributeContent :: Name -> Element -> Maybe [Content]+attributeContent name e = lookup name (elementAttributes e)++attributeText :: Name -> Element -> Maybe Text+attributeText name e = fmap contentFlat (attributeContent name e)++contentText :: Content -> [Text]+contentText (ContentText t) = [t]+contentText (ContentEntity entity) = [T.pack "&", entity, T.pack ";"]++contentFlat :: [Content] -> Text+contentFlat cs = T.concat (cs >>= contentText)
− license.txt
@@ -1,22 +0,0 @@-Copyright (c) 2010 John Millikin--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:--The above copyright notice and this permission notice shall be-included in all copies or substantial portions of the Software.--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.
xml-types.cabal view
@@ -1,25 +1,46 @@ name: xml-types-version: 0.1.4+version: 0.3.8 synopsis: Basic types for representing XML license: MIT-license-file: license.txt+license-file: COPYING author: John Millikin <jmillikin@gmail.com>-maintainer: jmillikin@gmail.com+maintainer: Stephen Paul Weber <singpolyma@singpolyma.net> build-type: Simple-cabal-version: >=1.6+cabal-version: >= 1.10 category: Text, XML stability: experimental-bug-reports: mailto:jmillikin@gmail.com+homepage: https://git.singpolyma.net/xml-types-haskell+bug-reports: mailto:dev@singpolyma.net+description:+ Basic types for representing XML.+ .+ The idea is to have a full set of appropriate types, which various XML+ libraries can share. Instead of having equivalent-but-incompatible types+ for every binding, parser, or client, they all share the same types can+ can thus interoperate easily.+ .+ This library contains complete types for most parts of an XML document,+ including the prologue, node tree, and doctype. Some basic combinators+ are included for common tasks, including traversing the node tree and+ filtering children. source-repository head- type: bazaar- location: http://john-millikin.com/software/xml-types/+ type: git+ location: https://git.singpolyma.net/xml-types-haskell +source-repository this+ type: git+ location: https://git.singpolyma.net/xml-types-haskell+ tag: 0.3.8+ library+ default-language: Haskell2010 ghc-options: -Wall+ hs-source-dirs: lib build-depends:- base >=3 && < 5+ base >= 3.0 && < 5.0+ , deepseq >= 1.1.0.0 , text exposed-modules: