-- | -- Convert an XPath result set into a node set -- module Text.XML.HXT.XPath.XPathToNodeSet ( xPValue2XmlNodeSet , emptyXmlNodeSet ) where import Text.XML.HXT.DOM.TypeDefs import Text.XML.HXT.XPath.XPathDataTypes -- ----------------------------------------------------------------------------- -- | -- Convert a a XPath-value into a XmlNodeSet represented by a tree structure -- -- The XmlNodeSet can be used to traverse a tree an process all -- marked nodes. xPValue2XmlNodeSet :: XPathValue -> XmlNodeSet xPValue2XmlNodeSet (XPVNode ns) = toNodeSet' ns xPValue2XmlNodeSet _ = emptyXmlNodeSet emptyXmlNodeSet :: XmlNodeSet emptyXmlNodeSet = XNS False [] [] leafNodeSet :: XmlNodeSet leafNodeSet = XNS True [] [] toNodeSet' :: NodeSet -> XmlNodeSet toNodeSet' = pathListToNodeSet . map toPath . fromNodeSet toPath :: NavXmlTree -> XmlNodeSet toPath = upTree leafNodeSet upTree :: XmlNodeSet -> NavXmlTree -> XmlNodeSet upTree ps (NT _ _ [] _ _) = ps -- root node reached upTree ps (NT (NTree n _) ix par _left _right) = upTree ps' $ head par where ps' = pix n pix (XAttr qn) = XNS False [qn] [] pix _ = XNS False [] [(ix, ps)] pathListToNodeSet ::[XmlNodeSet] -> XmlNodeSet pathListToNodeSet = foldr mergePaths emptyXmlNodeSet where mergePaths (XNS p1 al1 cl1) (XNS p2 al2 cl2) = XNS (p1 || p2) (al1 ++ al2) (mergeSubPaths cl1 cl2) mergeSubPaths [] sp2 = sp2 mergeSubPaths (s1:sp1) sp2 = mergeSubPath s1 (mergeSubPaths sp1 sp2) mergeSubPath s1 [] = [s1] mergeSubPath s1@(ix1,p1) sl@(s2@(ix2, p2) : sl') | ix1 < ix2 = s1 : sl | ix1 > ix2 = s2 : mergeSubPath s1 sl' -- ordered insert of s1 | otherwise = (ix1, mergePaths p1 p2) : sl' -- same ix merge subpaths -- -----------------------------------------------------------------------------