Question

I'm having some problems with HXT, though I suspect it's just something I'm missing about arrows.

I have an XML structure like

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

And internal structure like

data XmlData = XmlStr String | XmlList XmlData

Is there a way to collect elements at a step in an arrow?

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

The recursive call to getXmlData needs to collect it's answer and wrap in an XmlList constructor, but I don't know how to collect terms. Currently I'm accomplishing this with some post processing on the output (collecting on the same name), but I would like a better solution.

Was it helpful?

Solution

In general you can use listA from Control.Arrow.ArrowList to do this. It has type (ArrowList a) => a b c -> a b [c] and is a

combinator for converting an arrow into a determinstic version with all results collected in a single element list.

(See my answers here and here for a concrete example.)

In this specific case you can use the >. combinator with the XmlList constructor as its second argument to accomplish the same thing more concisely.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top