-- Copyright (c) 2010 John Millikin---- Permission is hereby granted, free of charge, to any person-- obtaining a copy of this software and associated documentation-- files (the "Software"), to deal in the Software without-- restriction, including without limitation the rights to use,-- copy, modify, merge, publish, distribute, sublicense, and/or sell-- copies of the Software, and to permit persons to whom the-- Software is furnished to do so, subject to the following-- conditions:---- The above copyright notice and this permission notice shall be-- included in all copies or substantial portions of the Software.---- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,-- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES-- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND-- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT-- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,-- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING-- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR-- OTHER DEALINGS IN THE SOFTWARE.moduleData.XML.Types(-- * Types-- ** Document prologueDocument(..),Prologue(..),Instruction(..),Miscellaneous(..)-- ** Document body,Node(..),Element(..),Attribute(..),Content(..),Name(..),Named(..)-- ** Doctypes,Doctype(..),ExternalID(..),InternalSubset-- ** Incremental processing,Event(..)-- * Predicates,isElement,isInstruction,isContent,isComment,isNamed-- * Filters,nodeChildren,elementChildren,hasAttribute,position)whereimportControl.Monad((>=>))importData.Text.Lazy(Text)importqualifiedData.Text.LazyasTimportData.String(IsString,fromString)importData.Function(on)dataDocument=Document{documentPrologue::Prologue,documentRoot::Element,documentEpilogue::[Miscellaneous]}deriving(Show,Eq)dataPrologue=Prologue{prologueBefore::[Miscellaneous],prologueDoctype::MaybeDoctype,prologueAfter::[Miscellaneous]}deriving(Show,Eq)dataInstruction=Instruction{instructionTarget::Text,instructionData::Text}deriving(Show,Eq,Ord)dataMiscellaneous=MiscInstructionInstruction|MiscCommentTextderiving(Show,Eq)dataNode=NodeElementElement|NodeInstructionInstruction|NodeContentContent|NodeCommentTextderiving(Show,Eq)dataElement=Element{elementName::Name,elementAttributes::[Attribute],elementNodes::[Node]}deriving(Show,Eq)dataAttribute=Attribute{attributeName::Name,attributeContent::[Content]}deriving(Show,Eq)dataContent=ContentTextText|ContentEntityTextderiving(Show,Eq)dataName=Name{nameLocalName::Text,nameNamespace::MaybeText,namePrefix::MaybeText}deriving(Show)-- | Ignores prefixesinstanceEqNamewhere(==)=(==)`on`(\x->(nameNamespacex,nameLocalNamex))-- | Ignores prefixes---- Since 0.1.3instanceOrdNamewherecompare=compare`on`(\x->(nameNamespacex,nameLocalNamex))-- | Supports Clark notation; see <http://www.jclark.com/xml/xmlns.htm> and-- <http://infohost.nmt.edu/tcc/help/pubs/pylxml/etree-QName.html>---- Since 0.1.2instanceIsStringNamewherefromString""=NameT.emptyNothingNothingfromStringfull@('{':rest)=casebreak(=='}')restof(_,"")->error("Invalid Clark notation: "++showfull)(ns,local)->Name(T.pack(drop1local))(Just(T.packns))NothingfromStringlocal=Name(T.packlocal)NothingNothingclassNamedawheregetName::a->NameinstanceNamedElementwheregetName=elementNameinstanceNamedAttributewheregetName=attributeNamedataDoctype=Doctype{doctypeName::Text,doctypeExternalID::MaybeExternalID,doctypeInternalSubsets::[InternalSubset]}deriving(Show,Eq)-- | Since 0.1.3instanceOrdDoctypewherecompare=compare`on`(\x->(doctypeNamex,doctypeExternalIDx))dataExternalID=SystemIDText|PublicIDTextTextderiving(Show,Eq,Ord)dataInternalSubset=InternalSubset-- TODOderiving(Show,Eq)-- | Some XML processing tools are incremental, and work in terms of events-- rather than node trees. Defining the event type here, even though it won't-- be useful to most users, allows these packages to interoperate more easily.---- Since: 0.1.1dataEvent=EventBeginDocument|EventEndDocument|EventInstructionInstruction|EventDoctypeDoctype|EventBeginElementName[Attribute]|EventEndElementName|EventContentContent|EventCommentTextderiving(Show,Eq)isElement::Node->[Element]isElement(NodeElemente)=[e]isElement_=[]isInstruction::Node->[Instruction]isInstruction(NodeInstructioni)=[i]isInstruction_=[]isContent::Node->[Content]isContent(NodeContentc)=[c]isContent_=[]isComment::Node->[Text]isComment(NodeCommentt)=[t]isComment_=[]isNamed::Nameda=>Name->a->[a]isNamednx=[x|getNamex==n]elementChildren::Element->[Element]elementChildren=elementNodes>=>isElement-- | Since 0.1.3elementContent::Element->[Content]elementContent=elementNodes>=>isContentnodeChildren::Node->[Node]nodeChildren=isElement>=>elementNodesposition::Integer->(a->[b])->a->[b]positionnfe=safeHeadn(fe)safeHead::Integer->[a]->[a]safeHead_[]=[]safeHead0(x:_)=[x]safeHeadn(_:xs)=safeHead(n-1)xshasAttribute::(Attribute->[Attribute])->Element->[Element]hasAttributefe=[e|not$null(elementAttributese>>=f)]