|HaXml-1.13.2: Utilities for manipulating XML documents||Contents||Index|
This module defines the notion of filters and filter combinators
for processing XML documents.
These XML transformation combinators are described in the paper
``Haskell and XML: Generic Combinators or Type-Based Translation?''
Malcolm Wallace and Colin Runciman, Proceedings ICFP'99.
|The content filter type.
|type CFilter = Content -> [Content]|
|All document transformations are content filters.
A filter takes a single XML Content value and returns a sequence
of Content values, possibly empty.
|In the algebra of combinators, none is the zero, and keep the identity.
(They have a more general type than just CFilter.)
|keep :: a -> [a]|
|none :: a -> [a]|
|children :: CFilter|
|Throw away current node, keep just the (unprocessed) children.
|position :: Int -> CFilter -> CFilter|
|Select the n'th positional result of a filter.
|These filters either keep or throw away some content based on
a simple test. For instance, elm keeps only a tagged element,
txt keeps only non-element text, tag keeps only an element
with the named tag, attr keeps only an element with the named
attribute, attrval keeps only an element with the given
attribute value, tagWith keeps only an element whose tag name
satisfies the given predicate.
|elm :: CFilter|
|txt :: CFilter|
|tag :: String -> CFilter|
|attr :: Name -> CFilter|
|attrval :: Attribute -> CFilter|
|tagWith :: (String -> Bool) -> CFilter|
|find :: String -> (String -> CFilter) -> CFilter|
|For a mandatory attribute field, find key cont looks up the value of
the attribute name key, and applies the continuation cont to
|iffind :: String -> (String -> CFilter) -> CFilter -> CFilter|
|When an attribute field may be absent, use iffind key yes no to lookup
its value. If the attribute is absent, it acts as the no filter,
otherwise it applies the yes filter.
|ifTxt :: (String -> CFilter) -> CFilter -> CFilter|
|ifTxt yes no processes any textual content with the yes filter,
but otherwise is the same as the no filter.
|o :: CFilter -> CFilter -> CFilter|
|Sequential (Irish,backwards) composition
|union :: (a -> [b]) -> (a -> [b]) -> a -> [b]|
|Binary parallel composition. Each filter uses a copy of the input,
rather than one filter using the result of the other.
(Has a more general type than just CFilter.)
|cat :: [a -> [b]] -> a -> [b]|
|Glue a list of filters together. (A list version of union;
also has a more general type than just CFilter.)
|andThen :: (a -> c) -> (c -> a -> b) -> a -> b|
|A special form of filter composition where the second filter
works over the same data as the first, but also uses the
|(|>|) :: (a -> [b]) -> (a -> [b]) -> a -> [b]|
in f |>| g give g-productions only if no f-productions
|with :: CFilter -> CFilter -> CFilter|
|Pruning: in f with g,
keep only those f-productions which have at least one g-production
|without :: CFilter -> CFilter -> CFilter|
|Pruning: in f without g,
keep only those f-productions which have no g-productions
|(/>) :: CFilter -> CFilter -> CFilter|
|Pronounced slash, f /> g means g inside f
|(</) :: CFilter -> CFilter -> CFilter|
|Pronounced outside, f </ g means f containing g
|et :: (String -> CFilter) -> CFilter -> CFilter|
|Join an element-matching filter with a text-only filter
|path :: [CFilter] -> CFilter|
|Express a list of filters like an XPath query, e.g.
path [children, tag "name1", attr "attr1", children, tag "name2"]
is like the XPath query /name1[@attr1]/name2.
|Recursive search has three variants: deep does a breadth-first
search of the tree, deepest does a depth-first search, multi returns
content at all tree-levels, even those strictly contained within results
that have already been returned.
|deep :: CFilter -> CFilter|
|deepest :: CFilter -> CFilter|
|multi :: CFilter -> CFilter|
|when :: CFilter -> CFilter -> CFilter|
f when g applies f only when the predicate g succeeds,
otherwise the content is unchanged.
|guards :: CFilter -> CFilter -> CFilter|
g guards f applies f only when the predicate g succeeds,
otherwise the content is discarded.
|chip :: CFilter -> CFilter|
|Process CHildren In Place. The filter is applied to any children
of an element content, and the element rebuilt around the results.
|foldXml :: CFilter -> CFilter|
|Recursive application of filters: a fold-like operator. Defined
as f o chip (foldXml f).
|mkElem :: String -> [CFilter] -> CFilter|
|Build an element with the given tag name - its content is the results
of the given list of filters.
|mkElemAttr :: String -> [(String, CFilter)] -> [CFilter] -> CFilter|
|Build an element with the given name, attributes, and content.
|literal :: String -> CFilter|
|Build some textual content.
|cdata :: String -> CFilter|
|Build some CDATA content.
|replaceTag :: String -> CFilter|
|Rename an element tag.
|replaceAttrs :: [(String, String)] -> CFilter|
|Replace the attributes of an element.
These definitions provide C-like conditionals, lifted to the filter level.
The (cond ? yes : no) style in C becomes (cond ?> yes :> no) in Haskell.
|data ThenElse a|
|Conjoin the two branches of a conditional.
|(?>) :: (a -> [b]) -> ThenElse (a -> [b]) -> a -> [b]|
|Select between the two branches of a joined conditional.
|Filters with labelled results.
|type LabelFilter a = Content -> [(a, Content)]|
|A LabelFilter is like a CFilter except that it pairs up a polymorphic
value (label) with each of its results.
|Using and combining labelled filters.
|oo :: (a -> CFilter) -> LabelFilter a -> CFilter|
|Compose a label-processing filter with a label-generating filter.
|x :: (CFilter -> LabelFilter a) -> (CFilter -> LabelFilter b) -> CFilter -> LabelFilter (a, b)|
|Combine labels. Think of this as a pair-wise zip on labels.
|Some label-generating filters.
|numbered :: CFilter -> LabelFilter String|
|Number the results from 1 upwards.
|interspersed :: String -> CFilter -> String -> LabelFilter String|
|In interspersed a f b, label each result of f with the string a,
except for the last one which is labelled with the string b.
|tagged :: CFilter -> LabelFilter String|
|Label each element in the result with its tag name. Non-element
results get an empty string label.
|attributed :: String -> CFilter -> LabelFilter String|
|Label each element in the result with the value of the named attribute.
Elements without the attribute, and non-element results, get an
empty string label.
|textlabelled :: CFilter -> LabelFilter (Maybe String)|
|Label each textual part of the result with its text. Element
results get an empty string label.
|extracted :: (Content -> a) -> CFilter -> LabelFilter a|
|Label each content with some information extracted from itself.
|Produced by Haddock version 0.8|