haskell xml update text using HXT library

家住魔仙堡 提交于 2020-04-15 17:16:21

问题


I need to have a possibility to update text in structure like this <node><data key="attr">text</data></node>. Is there any way to do this by using HXT library in haskell?


回答1:


The natural answer is a lens library; I don't think hxt has such a thing associated with it. But there is xml-lens which uses xml-conduit (but not conduits in fact)

The examples in the readme https://github.com/fumieval/xml-lens are fairly straightforward, but maybe a bit operator-clogged, if you aren't familiar with lenses. But here is less dense version of one of the examples. It modifies each page number in a book list by adding " pages" to it, changing

  <pages>360</pages>

to

  <pages>360 pages</pages>

starting with an XML like this:

<?xml version="1.0" encoding="ISO-8859-1"?>
<books>
<book category="Textbooks">
    <title>Learn You a Haskell for Great Good!</title>
    <author year="2011">Miran Lipovaca</author>
    <pages>360</pages>
</book>
<book category="Textbooks">
    <title>Programming in Haskell</title>
    <author year="2007">Graham Hutton</author>
    <pages>200</pages>
</book>
</books>

We need imports like these

  >>> import Text.XML.Lens        -- from the lens-xml package
  >>> import Control.Lens         -- from the lens package
  >>> import Text.XML             -- from the xml-conduit package
  >>> import Data.Monoid ((<>))
  >>> import qualified Data.Text as T
  >>> import qualified Data.ByteString.Lazy.Char8 as BL
  >>> :set -XOverloadedStrings    -- for Text literals

First I define the traversal that targets what I want to change:

  >>> let my_focus = root . el "books" ./ el "book" ./ el "pages" . text

then I define an ordinary Haskell function in terms of it, using over some_traversal some_function

  >>> let my_transformation = over my_focus (<> " pages") -- i.e. apply (<> " pages") to
  >>> :t my_transformation                                -- all the focused positions
  my_transformation :: Document -> Document

read the document:

  >>> doc <- Text.XML.readFile def "book.xml" 
  >>> :t doc
  doc :: Document

and then transform and render it:

  >>> BL.putStrLn $ renderLBS def (my_transformation doc)
  <?xml version="1.0" encoding="UTF-8"?><books>
  <book category="Textbooks">
      <title>Learn You a Haskell for Great Good!</title>
      <author year="2011">Miran Lipovaca</author>
      <pages>360 pages</pages>
  </book>
  <book category="Textbooks">
      <title>Programming in Haskell</title>
      <author year="2007">Graham Hutton</author>
      <pages>200 pages</pages>
  </book>
  </books>

This might be a little slow given the fancy apparatus it is using below the surface, but is plainly crazy powerful.



来源:https://stackoverflow.com/questions/37269316/haskell-xml-update-text-using-hxt-library

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!