2

我正在尝试使用 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] ]。

我究竟做错了什么?

4

2 回答 2

2

您可以使用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

这将打印您想要的结果。

请注意,我使用的是提供的/>andhasName而不是您的atTag,但如果您想坚持使用atTag.

于 2012-11-20T11:41:23.067 回答
0

它不是 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]
于 2012-11-15T07:10:48.187 回答