据我所知,正常的HXT似乎更倾向于XML的查询,而不是XML AST重构。然而,其中一个HXT模块,Data.Tree.NTree.Zippers.TypeDefs
似乎有一些机制可以潜入文档并进行本地工作,而不是更全局的箭头。但是,我似乎无法得到任何工作。这是my earlier HXT issue的后续帖子 - 所有代码都相同,但现在trans
正在替换this
。
以下是我的计划的切入点:
start :: App -> IO [XmlTree]
start (App src dest) = runX $
readDocument [
--... some settings ...
]
src
>>>
trans
>>>
writeDocument [
--... some settings ...
]
dest
以下是定义trans
的模块:
module Main.Internal where
import Data.Maybe (fromJust)
import Text.XML.HXT.DOM.XmlNode (mkText')
import Text.XML.HXT.Core hiding (addToTheRight)
import Data.Tree.NTree.Zipper.TypeDefs
trans :: IOSLA (XIOState s) XmlTree XmlTree
trans = arrL go
where
go :: XmlTree -> [XmlTree]
go x = [fromNTZipper . manip . toNTZipper $ x]
unList :: [a] -> a
unList [] = error "dun goofed!"
unList (x:_) = x
manip = fromJust . (addToTheRight $ mkText' "bar")
. fromJust . down
最后,这是我的输入文件:
<html>
<head>
<title>foo</title>
</head>
<body>
<h1>foo</h1>
</body>
</html>
和我的输出:
<?xml version="1.0" encoding="US-ASCII"?>
<html>
<head>
<title>foo</title>
</head>
<body>
<h1>foo</h1>
</body>
</html>
那么,为什么在我的输出中找不到“bar”?它不应该出现在</html>
之后吗?任何帮助都会很棒:)
答案 0 :(得分:1)
您的想法似乎很可靠,而且我不确定您的错误在哪里,但在玩弄它我能够生成测试代码:
import Data.Tree.NTree.Zipper.TypeDefs
import Text.XML.HXT.Parser.HtmlParsec
import Text.XML.HXT.DOM.XmlNode
import Text.XML.HXT.DOM.TypeDefs
import Data.Tree.NTree.TypeDefs
import Control.Arrow.IOListArrow
import Text.XML.HXT.Arrow.WriteDocument
str = "<html>\n <head>\n <title>foo</title>\n </head>\n <body>\n <h1>foo</h1>\n </body>\n</html>"
fromJust (Just x) = x
manip :: NTree XNode -> NTree XNode
manip x = fromNTZipper $ fromJust $
down (toNTZipper x) >>= addToTheLeft (mkText "Boo!") >>= up
stringify = runIOLA $ writeDocumentToString []
main = do
xs <- mapM stringify $ map manip $ parseHtmlDocument "" str
putStrLn (show xs)
输出[["\n Boo!<head>\n <title>foo</title>\n </head>\n <body>\n <h1>foo</h1>\n </body>\n"]]
。我实际上并不确定<html>
元素发生了什么,但addToTheLeft
完全按照它所说的做了。 (我正在使用>>=
上面的Maybe monad。
我不知道它是trans
还是>>>
,但你正在做的manip
似乎应该有效。< / p>
编辑:请注意,我上面写的很多内容避免了那些对HXT至关重要的惯用箭头,这可能就是我为什么会这样做的原因。得到一些奇怪的结果。从包结构看,导入Text.XML.HXT.Core
足以通常读取字符串和文档。以下适用于我:
Prelude> let file = "<html>\n <head>\n <title>foo</title>\n </head>\n <body>\n <h1>foo</h1>\n </body>\n</html>"
Prelude> :m +Text.XML.HXT.Core
Prelude Text.XML.HXT.Core> let apply (arrows) str = head $ runLA (xshow $ hread >>> arrows) str
Prelude Text.XML.HXT.Core> :t apply
apply :: LA XmlTree XmlTree -> String -> String
Prelude Text.XML.HXT.Core> putStrLn $ apply (withNav $ moveDown >>> addToTheLeft (txt "bar") >>> moveUp) file
<html>bar
<head>
<title>foo</title>
</head>
<body>
<h1>foo</h1>
</body>
</html>
所以那些是相关的功能。请注意,HXT似乎已经通过破坏列表(Maybe
列表箭头中)不满足给定谓词的XML树来执行其LA
内容。