File: Qualified.hs

package info (click to toggle)
haskell-hexpat 0.20.13-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 916 kB
  • sloc: ansic: 12,303; haskell: 3,457; xml: 1,109; makefile: 5; sh: 5
file content (70 lines) | stat: -rw-r--r-- 2,419 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
-- hexpat, a Haskell wrapper for expat
-- Copyright (C) 2008 Evan Martin <martine@danga.com>
-- Copyright (C) 2009 Stephen Blackheath <http://blacksapphire.com/antispam>

-- | In the default representation, qualified tag and attribute names such as
-- \<abc:hello\> are represented just as a string containing a colon, e.g.
-- \"abc:hello\".
--
-- This module provides functionality to handle these more intelligently, splitting
-- all tag and attribute names into their Prefix and LocalPart components.

module Text.XML.Expat.Internal.Qualified (
        QName(..),
        QAttributes,
        mkQName,
        mkAnQName,
        toQualified,
        fromQualified
    ) where

import Text.XML.Expat.Internal.NodeClass
import Text.XML.Expat.SAX
import Control.DeepSeq
import Data.Monoid

-- | A qualified name.
--
-- Qualified names have two parts, a prefix and a local part. The local part
-- is the name of the tag. The prefix scopes that name to a particular
-- group of legal tags.
--
-- The prefix will usually be associated with a namespace URI. This is usually
-- achieved by using xmlns attributes to bind prefixes to URIs.
data QName text =
    QName {
        qnPrefix    :: Maybe text,
        qnLocalPart :: !text
    }
    deriving (Eq,Show)

instance NFData text => NFData (QName text) where
    rnf (QName pre loc) = rnf (pre, loc)

-- | Type shortcut for attributes with qualified names
type QAttributes text = Attributes (QName text) text

-- | Make a new QName from a prefix and localPart.
mkQName :: text -> text -> QName text
mkQName prefix localPart = QName (Just prefix) localPart

-- | Make a new QName with no prefix.
mkAnQName :: text -> QName text
mkAnQName localPart = QName Nothing localPart

toQualified :: (NodeClass n c, GenericXMLString text) => n c text text -> n c (QName text) text
toQualified = mapAllTags qual
  where
    qual ident =
        case gxBreakOn ':' ident of
             (prefix, _local) | not (gxNullString _local)
                              && gxHead _local == ':'
                                 -> QName (Just prefix) (gxTail _local)
             _                   -> QName Nothing ident

fromQualified :: (NodeClass n c, GenericXMLString text) => n c (QName text) text -> n c text text
fromQualified = mapAllTags tag
  where
    tag (QName (Just prefix) local) = prefix `mappend` gxFromChar ':' `mappend` local
    tag (QName Nothing       local) = local