在 Arrow proc 上下文中提取多个元素

Extract multiple elements in an Arrow proc context

我想在没有 pickler 模块的情况下解析以下示例 XML 文件。

<?xml version="1.0" encoding="utf-8" ?>
<Groups> 
    <Name>ABC</Name>
    <GroupA>
        <Name>Foo</Name>
        <Sum>100</Sum>
    </GroupA>
    <GroupB>
        <Name>Bar</Name>
        <Sum>0</Sum>
    </GroupB>
</Groups>

我最终得到了这个:

{-# language Arrows #-}

import Text.XML.HXT.Core

data Groups = Groups GroupA GroupB deriving Show
data GroupA = GroupA String String deriving Show
data GroupB = GroupB String String deriving Show


readGroup :: LA XmlTree Groups
readGroup = deep (isElem >>> hasName "Groups") >>> getChildren >>>
  proc root -> do
    a <- readGroupA -< root
    b <- readGroupB -< root
    returnA -< Groups a b

readGroupA :: LA XmlTree GroupA
readGroupA = isElem >>> hasName "GroupA" >>> getChildren >>>
  proc root -> do
    n <- isElem >>> hasName "Name" /> getText -< root
    s <- isElem >>> hasName "Sum"  /> getText -< root
    returnA -< GroupA n s

readGroupB :: LA XmlTree GroupB
readGroupB = isElem >>> hasName "GroupB" >>> getChildren >>>
  proc root -> do
    n <- isElem >>> hasName "Name" /> getText -< root
    s <- isElem >>> hasName "Sum"  /> getText -< root
    returnA -< GroupB n s

不幸的是,这不起作用。 如果我尝试在 proc 上下文中提取单个元素,它会起作用。 但是尝试提取多个元素总是会失败\ return 空列表。我可能对作文有误解 >>>.

我运行和runLa (xreadDoc >>> readGroups)的例子

试试这个:

readGroup :: LA XmlTree Groups
readGroup = deep (isElem >>> hasName "Groups") >>>
  proc root -> do
    a <- getChildren >>> readGroupA -< root
    b <- getChildren >>> readGroupB -< root
    returnA -< Groups a b

readGroupA :: LA XmlTree GroupA
readGroupA = isElem >>> hasName "GroupA" >>>
  proc root -> do
    n <- getChildren >>> isElem >>> hasName "Name" /> getText -< root
    s <- getChildren >>> isElem >>> hasName "Sum"  /> getText -< root
    returnA -< GroupA n s

readGroupB :: LA XmlTree GroupB
readGroupB = isElem >>> hasName "GroupB" >>>
  proc root -> do
    n <- getChildren >>> isElem >>> hasName "Name" /> getText -< root
    s <- getChildren >>> isElem >>> hasName "Sum"  /> getText -< root
    returnA -< GroupB n s

当对 getChildren 的调用在 do 块之外时,您甚至在进入 proc 之前就提交了一个 child。在 proc 中,您检查(例如)child 是否有名称 Name 名称 Sum。不出所料,您找不到任何 child 满足这些相互矛盾的要求。

通过将 getChildren 移动到内部,您可以为(例如)ns.

遍历不同的 children