我想以html格式输出一个表格。 基本上我想要像:
[[a]] -> <table>
最简单的方法是什么?
答案 0 :(得分:7)
生成Html的最简单方法可能是blaze:
import Text.Blaze.Html5 (table, td, tr, toHtml, ToMarkup, Html)
import Control.Monad (forM_, mapM_)
myTable :: (ToMarkup a) => [[a]] -> Html
myTable xs = table $ forM_ xs (tr . mapM_ (td . toHtml))
请注意,您需要使用renderHtml
中的Text.Blaze.Renderer.*
来获取ByteString
,String
或Text
。
答案 1 :(得分:3)
编辑:在撰写答案期间,@ Zeta已使用blaze-html
发布了更好的解决方案。所以我建议使用他的解决方案(参见&#34;警告词&#34;听取这个解决方案的缺点......); - )
这是一个实现:
-- file test.hs:
insideTag :: String -> String -> String
insideTag tag content = "<" ++ tag ++ ">" ++ content ++ "</" ++ tag ++ ">"
toTable :: Show a => [[a]] -> String
toTable = insideTag "table" . concatMap (insideTag "tr") . map (concatMap (insideTag "td" . show))
main :: IO ()
main = do
putStrLn $ toTable [[1,2,3],[4,5,6],[7,8,9]]
return ()
命令runhaskell test.hs
现在将打印
<table><tr><td>1</td><td>2</td><td>3</td></tr><tr><td>4</td><td>5</td><td>6</td></tr><tr><td>7</td><td>8</td><td>9</td></tr></table>
insideTag
将内容封装在html标记内:
ghci> let insideTag tag content = "<" ++ tag ++ ">" ++ content ++ "</" ++ tag ++ ">"
ghci> insideTag "h1" "hello world"
"<h1>hello world</h1>"
map (concatMap (insideTag "td" . show)) list
将内部元素封装到<td>
标记中并将它们连接起来:
ghci> map (concatMap (insideTag "td" . show)) [[1,2], [3,4]]
["<td>1</td><td>2</td>","<td>3</td><td>4</td>"]
外部列表也可以这样做:
ghci> concatMap (insideTag "tr") ["<td>1</td><td>2</td>","<td>3</td><td>4</td>"]
"<tr><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr>"
最后一个字符串只需封装到<table>
标记中:
ghci> insideTag "table" "<tr><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr>"
"<table><tr><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr></table>"
上面的代码使用普通的[Char]
类型表示不具有内存效率的字符串。因此,如果您处理大表格,我建议您使用Data.Text toTable
保持不变,您只需将show
更改为pack . show
; insideTag
为Data.Text
)重新实现。
表内容也没有HTML转义!!! 因此上述代码容易受到XSS attacts的攻击。因此,如果生成的HTML应包含在网站中(特别是如果网站用户对表格内容有影响),请不要使用上述代码!