2010-10-27 3 views
3

У меня возникли проблемы с HXT, хотя я подозреваю, что это просто что-то, что мне не хватает в стрелках.Свернуть все arrow

У меня есть структура XML как

<str name="field1">value</str> 
<lst name="field2"><str>value2</str><str>value3</str></lst> 

и внутренней структуры, как

data XmlData = XmlStr String | XmlList XmlData 

Есть ли способ, чтобы собрать на шаг в стрелке элементы?

getXmlData :: IOSArrow XmlTree (String, XmlData) 
getXmlData = (getAttrl >>> getChildren >>> getText) &&& 
     ((filterByType "str" >>> getText >>> arr (\x -> XmlStr x)) 
     <+> (filterByType "lst" >>> getXmlData)) 
    where filterByType t = isElem >>> hasName t >>> getChildren 

Рекурсивный вызов getXmlData должен собрать это ответ и завернуть в конструкторе XMLList, но я не знаю, как собрать термины. В настоящее время я выполняю это с некоторой пост-обработкой на выходе (собирая одноименное имя), но я бы хотел получить лучшее решение.

ответ

3

Для этого вы можете использовать listA от Control.Arrow.ArrowList. Он имеет тип (ArrowList a) => a b c -> a b [c] и является

комбинатор для преобразования стрелки в determinstic версии со всеми результатов, собранных в одном элементе списке.

(см моих ответов here и here для конкретного примера.)

В данном конкретном случае вы можете использовать >. комбинатор с XmlList конструктору в качестве второго аргумента, чтобы выполнить то же самое более лаконично.

+0

>. работал, когда я переместил вызов getChildren из помощника и добавил некоторые скобки. Мне было интересно узнать об использовании для listA, но не смог найти пример с ним в составе конвейера. Не могли бы вы предоставить решение с помощью listA? – amccausl

+1

@amccausl: В первом ответе, связанном выше, у нас есть недетерминированная стрелка с типом 'a XmlTree (String, String)' и мы хотим использовать ее с 'arr Data.Map.fromList' (типа' a [(String, String)] (M.Map String String) ') для заполнения карты. 'listA' позволяет нам сопоставлять типы стрелок, чтобы они могли быть скомпонованы. –

Смежные вопросы