-- ------------------------------------------------------------ {- | Module : Text.XML.HXT.DTDValidation.Validation Copyright : Copyright (C) 2008 Uwe Schmidt License : MIT Maintainer : Uwe Schmidt (uwe@fh-wedel.de) Stability : experimental Portability: portable This module provides functions for validating XML documents represented as XmlTree. Unlike other popular XML validation tools the validation functions return a list of errors instead of aborting after the first error was found. Note: The validation process has been split into validation and transformation! If @validate@ did not report any errors, @transform@ should be called, to change the document the way a validating parser is expected to do. -} -- ------------------------------------------------------------ module Text.XML.HXT.DTDValidation.Validation ( getDTDSubset , generalEntitiesDefined , validate , validateDTD , validateDoc , removeDoublicateDefs , transform ) where import Text.XML.HXT.DTDValidation.TypeDefs import qualified Text.XML.HXT.DTDValidation.DTDValidation as DTDValidation import qualified Text.XML.HXT.DTDValidation.DocValidation as DocValidation import qualified Text.XML.HXT.DTDValidation.IdValidation as IdValidation import qualified Text.XML.HXT.DTDValidation.DocTransformation as DocTransformation -- | -- Main validation filter. Check if the DTD and the document are valid. -- -- -- - returns : a function which expects a complete document as XmlTree input -- and returns a list of all errors found. validate :: XmlArrow validate = validateDTD <+> validateDoc -- | -- Check if the DTD is valid. -- -- -- - returns : a function which expects an XmlTree from the parser as input -- and returns a list of all errors found in the DTD. validateDTD :: XmlArrow validateDTD = choiceA [ getDTDSubset :-> DTDValidation.validateDTD , this :-> err "Can't validate DTD: There is no DOCTYPE declaration in the document." ] -- | -- Check if the document corresponds to the given DTD. -- -- -- - returns : a function which expects a complete document as XmlTree input -- and returns a list of all errors found in the content part. validateDoc :: XmlArrow validateDoc = validateDoc' $< getDTD where validateDoc' [] = err "Can't validate document: There is no DOCTYPE declaration in the document." validateDoc' (dtdPart:_) = DocValidation.validateDoc dtdPart <+> IdValidation.validateIds dtdPart getDTD :: XmlArrowS getDTD = listA ( getDTDSubset >>> removeDoublicateDefs ) -- | -- filter for transforming a document with respect to the given DTD. -- -- Validating parsers -- are expected to normalize attribute values and add default values. -- This function should be called after a successful validation. -- -- -- - returns : a function which expects a complete XML document tree -- and returns the transformed XmlTree transform :: XmlArrow transform = choiceA [ isRoot :-> (transformDoc $< getDTD) , this :-> fatal "Can't transform document: No document root given" ] where transformDoc [] = this transformDoc dtd = DocTransformation.transform (head dtd) -- | -- Removes doublicate declarations from the DTD which first declaration is -- binding. This is the case for ATTLIST and ENTITY declarations. -- -- -- - returns : A function that replaces the children of DOCTYPE nodes by a list -- where all multiple declarations are removed. removeDoublicateDefs :: XmlArrow removeDoublicateDefs = DTDValidation.removeDoublicateDefs -- -- selects the DTD part of a document -- but only, if there is more than the internal part for the 4 predefined XML entities getDTDSubset :: XmlArrow getDTDSubset = getChildren >>> ( filterA $ isDTDDoctype >>> getDTDAttrl >>> isA (hasEntry a_name) ) generalEntitiesDefined :: XmlArrow generalEntitiesDefined = getDTDSubset >>> deep isDTDEntity -- ------------------------------------------------------------