1

据我所知,与 XML AST 重构相比,普通 HXT 似乎更适合对 XML 的查询。但是,其中一个 HXT 模块Data.Tree.NTree.Zippers.TypeDefs似乎具有一些用于深入文档并进行本地工作的机制,而不是更全局的箭头。但是,我似乎无法得到任何工作。这是我之前的 HXT 问题的后续帖子- 所有代码都是相同的,除了现在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>吗?再次,任何帮助都会很棒:)

4

1 回答 1

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你正在做的似乎它应该工作。

编辑:请注意,我在上面写的很多内容都避免了 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通过破坏列表(LA列表箭头的)中不满足给定谓词的 XML 树来完成它的工作。

于 2014-11-06T00:21:55.220 回答