-- ------------------------------------------------------------

{- |
   Module     : Text.XML.HXT.XPath.XPathToString
   Copyright  : Copyright (C) 2008 - infinity: Uwe Schmidt
   License    : MIT

   Maintainer : Uwe Schmidt (uwe@fh-wedel.de)
   Stability  : experimental
   Portability: portable

   Format an expression or value in tree- or string-representation

-}

-- ------------------------------------------------------------

module Text.XML.HXT.XPath.XPathToString
    ( expr2XPathTree
    , xPValue2String
    , xPValue2XmlTrees
    , nt2XPathTree
    , pred2XPathTree
    , toXPathTree
    , formatXPathTree
    )
where

-- import Text.XML.HXT.DOM.XmlTree

import Text.XML.HXT.DOM.Interface
import Text.XML.HXT.DOM.XmlNode         ( mkText
                                        , mkError
                                        )
import Text.XML.HXT.DOM.FormatXmlTree   ( formatXmlTree )
import Text.XML.HXT.XPath.XPathDataTypes

import Data.Char                        ( toLower )
import Data.Tree.Class                  ( formatTree )

-- ------------------------------------------------------------

type XPathTree                          = NTree String

-- -----------------------------------------------------------------------------
-- |
-- Convert an navigable tree in a xmltree
--
toXPathTree                             :: [NavTree a] -> [NTree a]
toXPathTree :: forall a. [NavTree a] -> [NTree a]
toXPathTree                             = (NavTree a -> NTree a) -> [NavTree a] -> [NTree a]
forall a b. (a -> b) -> [a] -> [b]
map NavTree a -> NTree a
forall a. NavTree a -> NTree a
subtreeNT

-- -----------------------------------------------------------------------------

formatXPathTree                         :: Expr -> String
formatXPathTree :: Expr -> String
formatXPathTree                         = (String -> String) -> NTree String -> String
forall a. (a -> String) -> NTree a -> String
forall (t :: * -> *) a. Tree t => (a -> String) -> t a -> String
formatTree String -> String
forall a. a -> a
id (NTree String -> String)
-> (Expr -> NTree String) -> Expr -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> NTree String
expr2XPathTree

-- -----------------------------------------------------------------------------
-- |
-- Format a XPath-value in string representation.
-- Text output is done by 'formatXmlTree' for node-sets (trees),
-- all other values are represented as strings.
--

xPValue2String                          :: XPathValue -> String
xPValue2String :: XPathValue -> String
xPValue2String (XPVNode NodeSet
ns)             = (NTree XNode -> String -> String)
-> String -> [NTree XNode] -> String
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\ NTree XNode
t -> ((NTree XNode -> String
formatXmlTree NTree XNode
t String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n") String -> String -> String
forall a. [a] -> [a] -> [a]
++)) String
"" ([NavTree XNode] -> [NTree XNode]
forall a. [NavTree a] -> [NTree a]
toXPathTree ([NavTree XNode] -> [NTree XNode])
-> (NodeSet -> [NavTree XNode]) -> NodeSet -> [NTree XNode]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NodeSet -> [NavTree XNode]
fromNodeSet (NodeSet -> [NTree XNode]) -> NodeSet -> [NTree XNode]
forall a b. (a -> b) -> a -> b
$ NodeSet
ns)
xPValue2String (XPVBool Bool
b)              = (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower (Bool -> String
forall a. Show a => a -> String
show Bool
b)
xPValue2String (XPVNumber (Float Float
f))    = Float -> String
forall a. Show a => a -> String
show Float
f
xPValue2String (XPVNumber XPNumber
s)            = XPNumber -> String
forall a. Show a => a -> String
show XPNumber
s
xPValue2String (XPVString String
s)            = String
s
xPValue2String (XPVError String
s)             = String
"Error: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s

-- -----------------------------------------------------------------------------
-- |
-- Convert a a XPath-value into XmlTrees.
--

xPValue2XmlTrees                        :: XPathValue -> XmlTrees
xPValue2XmlTrees :: XPathValue -> [NTree XNode]
xPValue2XmlTrees (XPVNode NodeSet
ns)           = [NavTree XNode] -> [NTree XNode]
forall a. [NavTree a] -> [NTree a]
toXPathTree ([NavTree XNode] -> [NTree XNode])
-> (NodeSet -> [NavTree XNode]) -> NodeSet -> [NTree XNode]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NodeSet -> [NavTree XNode]
fromNodeSet (NodeSet -> [NTree XNode]) -> NodeSet -> [NTree XNode]
forall a b. (a -> b) -> a -> b
$ NodeSet
ns
xPValue2XmlTrees (XPVBool Bool
b)            = String -> [NTree XNode]
xtext (Bool -> String
forall a. Show a => a -> String
show Bool
b)
xPValue2XmlTrees (XPVNumber (Float Float
f))  = String -> [NTree XNode]
xtext (Float -> String
forall a. Show a => a -> String
show Float
f)
xPValue2XmlTrees (XPVNumber XPNumber
s)          = String -> [NTree XNode]
xtext (XPNumber -> String
forall a. Show a => a -> String
show XPNumber
s)
xPValue2XmlTrees (XPVString String
s)          = String -> [NTree XNode]
xtext String
s
xPValue2XmlTrees (XPVError  String
s)          = String -> [NTree XNode]
xerr String
s

xtext, xerr                             :: String -> XmlTrees
xtext :: String -> [NTree XNode]
xtext                                   = (NTree XNode -> [NTree XNode] -> [NTree XNode]
forall a. a -> [a] -> [a]
:[]) (NTree XNode -> [NTree XNode])
-> (String -> NTree XNode) -> String -> [NTree XNode]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> NTree XNode
forall a. XmlNode a => String -> a
mkText

xerr :: String -> [NTree XNode]
xerr                                    = (NTree XNode -> [NTree XNode] -> [NTree XNode]
forall a. a -> [a] -> [a]
:[]) (NTree XNode -> [NTree XNode])
-> (String -> NTree XNode) -> String -> [NTree XNode]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String -> NTree XNode
forall a. XmlNode a => Int -> String -> a
mkError Int
c_err


-- -----------------------------------------------------------------------------
-- |
-- Format a parsed XPath-expression in tree representation.
-- Text output is done by 'formatXmlTree'
--
expr2XPathTree                          :: Expr -> XPathTree
expr2XPathTree :: Expr -> NTree String
expr2XPathTree (GenExpr Op
op [Expr]
ex)          = String -> NTrees String -> NTree String
forall a. a -> NTrees a -> NTree a
NTree (Op -> String
forall a. Show a => a -> String
show Op
op) ((Expr -> NTree String) -> [Expr] -> NTrees String
forall a b. (a -> b) -> [a] -> [b]
map Expr -> NTree String
expr2XPathTree [Expr]
ex)
expr2XPathTree (NumberExpr XPNumber
f)           = String -> NTrees String -> NTree String
forall a. a -> NTrees a -> NTree a
NTree (XPNumber -> String
forall a. Show a => a -> String
show XPNumber
f) []
expr2XPathTree (LiteralExpr String
s)          = String -> NTrees String -> NTree String
forall a. a -> NTrees a -> NTree a
NTree String
s []
expr2XPathTree (VarExpr VarName
name)           = String -> NTrees String -> NTree String
forall a. a -> NTrees a -> NTree a
NTree (String
"Var: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ VarName -> String
forall a. Show a => a -> String
show VarName
name) []
expr2XPathTree (FctExpr String
n [Expr]
arg)          = String -> NTrees String -> NTree String
forall a. a -> NTrees a -> NTree a
NTree (String
"Fct: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
n) ((Expr -> NTree String) -> [Expr] -> NTrees String
forall a b. (a -> b) -> [a] -> [b]
map Expr -> NTree String
expr2XPathTree [Expr]
arg)

expr2XPathTree (FilterExpr [])          = String -> NTrees String -> NTree String
forall a. a -> NTrees a -> NTree a
NTree String
"" []
expr2XPathTree (FilterExpr (Expr
primary:[Expr]
predicate))
                                        = String -> NTrees String -> NTree String
forall a. a -> NTrees a -> NTree a
NTree String
"FilterExpr" [Expr -> NTree String
expr2XPathTree Expr
primary, [Expr] -> NTree String
pred2XPathTree [Expr]
predicate]

expr2XPathTree (PathExpr Maybe Expr
Nothing (Just LocationPath
lp))
                                        = LocationPath -> NTree String
locpath2XPathTree LocationPath
lp
expr2XPathTree (PathExpr (Just Expr
fe) (Just LocationPath
lp))
                                        = String -> NTrees String -> NTree String
forall a. a -> NTrees a -> NTree a
NTree String
"PathExpr" [Expr -> NTree String
expr2XPathTree Expr
fe, LocationPath -> NTree String
locpath2XPathTree LocationPath
lp]
expr2XPathTree (PathExpr Maybe Expr
_ Maybe LocationPath
_)           = String -> NTrees String -> NTree String
forall a. a -> NTrees a -> NTree a
NTree String
"" []

locpath2XPathTree                       :: LocationPath -> XPathTree
locpath2XPathTree :: LocationPath -> NTree String
locpath2XPathTree (LocPath Path
rel [XStep]
steps)   = String -> NTrees String -> NTree String
forall a. a -> NTrees a -> NTree a
NTree (Path -> String
forall a. Show a => a -> String
show Path
rel String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"LocationPath") ((XStep -> NTree String) -> [XStep] -> NTrees String
forall a b. (a -> b) -> [a] -> [b]
map XStep -> NTree String
step2XPathTree [XStep]
steps)


step2XPathTree                          :: XStep -> XPathTree
step2XPathTree :: XStep -> NTree String
step2XPathTree (Step AxisSpec
axis NodeTest
nt [])        = String -> NTrees String -> NTree String
forall a. a -> NTrees a -> NTree a
NTree (AxisSpec -> String
forall a. Show a => a -> String
show AxisSpec
axis) [NodeTest -> NTree String
nt2XPathTree NodeTest
nt]
step2XPathTree (Step AxisSpec
axis NodeTest
nt [Expr]
expr)      = String -> NTrees String -> NTree String
forall a. a -> NTrees a -> NTree a
NTree (AxisSpec -> String
forall a. Show a => a -> String
show AxisSpec
axis) [NodeTest -> NTree String
nt2XPathTree NodeTest
nt, [Expr] -> NTree String
pred2XPathTree [Expr]
expr]

nt2XPathTree                            :: NodeTest -> XPathTree
nt2XPathTree :: NodeTest -> NTree String
nt2XPathTree (TypeTest XPathNode
s)               = String -> NTrees String -> NTree String
forall a. a -> NTrees a -> NTree a
NTree (String
"TypeTest: "String -> String -> String
forall a. [a] -> [a] -> [a]
++ XPathNode -> String
typeTest2String XPathNode
s) []
nt2XPathTree (PI String
s)                     = String -> NTrees String -> NTree String
forall a. a -> NTrees a -> NTree a
NTree (String
"TypeTest: processing-instruction("String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")") []
nt2XPathTree (NameTest QName
s)               = String -> NTrees String -> NTree String
forall a. a -> NTrees a -> NTree a
NTree (String
"NameTest: "String -> String -> String
forall a. [a] -> [a] -> [a]
++ QName -> String
forall a. Show a => a -> String
show QName
s) []


pred2XPathTree                          :: [Expr] -> XPathTree
pred2XPathTree :: [Expr] -> NTree String
pred2XPathTree [Expr]
exprL                    = String -> NTrees String -> NTree String
forall a. a -> NTrees a -> NTree a
NTree String
"Predicates" ((Expr -> NTree String) -> [Expr] -> NTrees String
forall a b. (a -> b) -> [a] -> [b]
map Expr -> NTree String
expr2XPathTree [Expr]
exprL)

typeTest2String                         :: XPathNode -> String
typeTest2String :: XPathNode -> String
typeTest2String XPathNode
XPNode                  = String
"node()"
typeTest2String XPathNode
XPCommentNode           = String
"comment()"
typeTest2String XPathNode
XPPINode                = String
"processing-instruction()"
typeTest2String XPathNode
XPTextNode              = String
"text()"

-- ------------------------------------------------------------