[Haskell-cafe] Re: HaXml and the XHTML 1.0 Strict DTD

Peter Gammie peteg42 at gmail.com
Wed May 21 07:50:22 EDT 2008

On 21/05/2008, at 5:44 PM, Malcolm Wallace wrote:

> Peter Gammie <peteg42 at gmail.com> wrote:
>> <!ELEMENT table
>>      (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))>
>> Using a slightly hacked HaXml v1.13.3, I get this from DtdToHaskell:
>> data Table = Table Table_Attrs (Maybe Caption)
>>                    (OneOf2 [Col] [Colgroup]) (Maybe Thead) (Maybe  
>> Tfoot)
>>                    (OneOf2 (List1 Tbody) (List1 Tr))
>>            deriving (Eq,Show)
> This looks entirely correct to me.

I realised that as soon as I sent it. :-)

>> My expectation is that we can have a <table> without a <col> or
>> <colgroup> child.
> Ah, yes I can see why that is permitted, but I guess HaXml's validator
> is not yet smart enough to be able to choose whether it has seen an
> empty list of <col> or an empty list of <colgroup>.  :-)
> Here is a suggested fix.  Let me know if it works for you.  In
> src/Text/XML/HaXml/Validate.hs, around line 220, use the following  
> diff
> over the local defn of 'choice':
>    choice elem ns cps =  -- return only those parses that don't give  
> any errors
>        [ rem | ([],rem) <- map (\cp-> checkCP elem (definite cp) ns)  
> cps ]
> +       ++ [ ns | all possEmpty cps ]
>        where definite (TagName n Query)  = TagName n None
>              definite (Choice cps Query) = Choice cps None
>              definite (Seq cps Query)    = Seq cps None
>              definite (TagName n Star)   = TagName n Plus
>              definite (Choice cps Star)  = Choice cps Plus
>              definite (Seq cps Star)     = Seq cps Plus
>              definite x                  = x
> +             possEmpty (TagName _ mod)   = mod `elem` [Query,Star]
> +             possEmpty (Choice cps None) = all possEmpty cps
> +             possEmpty (Choice _ mod)    = mod `elem` [Query,Star]
> +             possEmpty (Seq cps None)    = all possEmpty cps
> +             possEmpty (Seq _ mod)       = mod `elem` [Query,Star]

Fantastic, thanks, that seems to work fine. A couple of nits: your use  
of `elem` refers to Prelude.elem, so I added the Prelude as a  
qualified import as P and changed those shadowed references to `P.elem`.

I will try to send you a patch against 1.13.3 with all these little  
bits and pieces, when my project is finished.

Can you lay out some kind of plan for HaXml? (is 1.13.x now dead, is  
1.19.x stable, ...?) This would help for new-ish projects like mine.

> Are there other places, apart from the validator, where a similar
> problem arises?

I do not know, I am merely using the DTD and HTML parsers, the CFilter  
combinators, the pretty printer and the validator. They all seem fine  
on a cursory check.

(In general HaXml has been working quite well. Thanks for producing  
such a long-lived and well-thought-out library.)


More information about the Haskell-Cafe mailing list