Catching and halting on syntax exceptions during parsing with HXT

59 Views Asked by At

Suppose an XML based language where the node attribute animal is illegal. Consider:

{-# LANGUAGE Arrows, RankNTypes #-}
module Lib ( parseXml ) where
import Control.Arrow
import Text.XML.HXT.Core

parseXml = runLA (xread >>> isElem >>> myParser) content
  where
    content = unlines
      [ "<pet animal='cat'>felix</pet>"
      , "<pet>milo</pet>"
      , "<pet animal='rat'>tom</pet>" ]

myParser :: (ArrowXml a) => a XmlTree [String]
myParser =  proc xml -> do
  x <- isElem -< xml
  pets <- (getText <<< getChildren <<< neg (hasAttr "animal")) >. id -< x
  returnA -< pets

The result of evaluating parseXml is:

parseXml
[[],["milo"],[]]

Which is not what is intended. The parser has silently ignored the 1st and 3rd XML nodes since they do not conform to the myParser, specifically neg (hasAttr "animal"), but I'd like the behaviour to not silently ignore them, but instead halt parsing at the 1st XML node.

How can I change this code such that HXT throw an error if it ever encounters our syntax violation that an XML node can never have an "animal" attribute? That is, when attempting to parse the 1st XML node it returns a Left value e.g.

parseXml
Left (ParseError "'animal' attribute is not permitted")
1

There are 1 best solutions below

1
On

Try err and its neighbors with when.