HXT:在纯代码中读取和写入HTML时出现令人惊讶的行为

时间:2011-08-26 17:42:53

标签: haskell hxt

我想从String中读取HTML,处理它并使用HXT将更改的文档作为String返回。由于此操作不需要IO,我宁愿使用runLA而不是runX执行箭头。

代码看起来像这样(为简单起见省略处理):

runLA (hread >>> writeDocumentToString [withOutputHTML, withIndent yes]) html

但是,结果中缺少周围的html标记:

["\n  <head>\n    <title>Bogus</title>\n  </head>\n  <body>\n        Some trivial bogus text.\n    </body>\n",""]

当我像这样使用runX时:

runX (readString [] html >>> writeDocumentToString [withOutputHTML, withIndent yes])

我得到了预期的结果:

["<html>\n  <head>\n    <title>Bogus</title>\n  </head>\n  <body>\n        Some trivial bogus text.\n    </body>\n</html>\n"]

为什么会这样,我该如何解决?

1 个答案:

答案 0 :(得分:6)

如果您查看两者的XmlTree,则会看到readString添加了顶级"/"元素。对于非IO runLA版本:

> putStr . formatTree show . head $ runLA xread html
---XTag "html" []
   |
   +---XText "\n  "
   |
   +---XTag "head" []
   ...

使用runX

> putStr . formatTree show . head =<< runX (readString [] html)
---XTag "/" [NTree (XAttr "transfer-Status") [NTree (XText "200")...
   |
   +---XTag "html" []
       |
       +---XText "\n  "
       |
       +---XTag "head" []
       ...

writeDocumentToString使用getChildren去除此根元素。

解决这个问题的一个简单方法是使用selem之类的东西将xread的输出包装在类似的根元素中,以使其看起来像输入类型writeDocumentToString预计:

> runLA (selem "/" [xread] >>> writeDocumentToString [withOutputHTML, withIndent yes]) html
["<html>\n  <head>\n    <title>Bogus</title>\n  </head>\n  <body>\n        Some trivial bogus text.\n    </body>\n</html>\n"]

这会产生所需的输出。