【问题标题】:Haskell HXT to parse rows and columns and getting [[String]] and not [String]Haskell HXT 解析行和列并获取 [[String]] 而不是 [String]
【发布时间】:2012-11-15 05:51:18
【问题描述】:

我正在尝试使用 HXT 解析 ods(libreoffice 电子表格)文件,但遇到了问题。 在电子表格中,一行有许多单元格(所有单元格名称都为“cell”),而电子表格有很多行(所有单元格名称为 row)。 当我尝试获取单元格的文本时,代码将它们混合在一起,最终得到一大堆不按行分隔的单元格......

尝试解析以下内容时:

<spreadsheet>
    <row>
       <cell> <p>ABC</p> </cell>
       <cell> <p>DEF</p> </cell>
       <cell> <p>GHI</p> </cell>
    </row>
    <row>
       <cell> <p>abc</p> </cell>
       <cell> <p>def</p> </cell>
       <cell> <p>ghi</p> </cell>
    </row>
    <row>
       <cell> <p>123</p> </cell>
       <cell> <p>456</p> </cell>
       <cell> <p>789</p> </cell>
    </row>
</spreadsheet>

附上代码:

import Text.XML.HXT.Core

play arg = do { results <- runX (processor arg) ; print results }
atTag x = getChildren >>> isElem >>> hasName x

processor filename =
    readDocument [withValidate no] filename >>>
    atTag "spreadsheet" >>>
    atTag "row" >>>
    atTag "cell" >>>
    atTag "p" >>>
    getChildren >>> getText

它给出 [ABC, DEF, GHI, abc, def, ghi, 123, 456, 789] 而我想要的是 [[ABC, DEF, GHI], [abc, def, ghi], [123, 456 , 789]]。

我做错了什么?

【问题讨论】:

  • atTag 的类型是什么?如果是Tree -&gt; [Tree],那么您应该可以先执行let rows = readDocument &gt;&gt;&gt; ... &gt;&gt; atTag "row",然后再执行map (\t -&gt; t &gt;&gt;&gt; atTag "cell" &gt;&gt;&gt; ... &gt;&gt;&gt; getText) rows,以获得满意的结果。虽然我从来没有使用过 HXT...

标签: list haskell spreadsheet hxt


【解决方案1】:

您可以使用listA 在适当的位置将结果收集到列表中:

import System.Environment (getArgs)
import Text.XML.HXT.Core

processor filename =
  readDocument [withValidate no] filename
    />  hasName "spreadsheet"
    />  hasName "row"
    >>> listA (getChildren >>> hasName "cell" /> hasName "p" /> getText)

main = fmap head getArgs >>= runX . processor >>= print

这将打印你想要的结果。

请注意,我使用的是提供的 /&gt;hasName,而不是您的 atTag,但如果您想坚持使用 atTag,则可以轻松翻译回来。

【讨论】:

    【解决方案2】:

    不是HXT,但是你可以用xml-conduit解决这个问题:

    {-# LANGUAGE OverloadedStrings #-}
    import Text.XML
    import Text.XML.Cursor
    import qualified Data.Text as T
    
    main = do
        c <- fmap fromDocument $ Text.XML.readFile def "foo.xml"
        print $ c $// element "row" >=> perRow
      where
        perRow row = [row $/ element "cell" >=> perCell]
        perCell cell = [T.strip $ T.concat $ cell $// content]
    

    【讨论】:

    • 非常感谢!有用!但保持问题开放。不过,仍然对如何使用 HXT 实现它感到好奇。
    猜你喜欢
    • 2017-02-11
    • 2013-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多