hxt-xpath (empty) → 8.5.0
raw patch · 33 files changed
+10578/−0 lines, 33 filesdep +basedep +containersdep +directorysetup-changed
Dependencies added: base, containers, directory, filepath, haskell98, hxt, parsec
Files
- LICENCE +9/−0
- Setup.lhs +8/−0
- examples/Makefile +17/−0
- examples/hunit/HUnitExample.hs +106/−0
- examples/hunit/Makefile +32/−0
- examples/hunit/mini1.xml +1/−0
- examples/hunit/mini2.xml +1/−0
- examples/hxpath/.ghci +4/−0
- examples/hxpath/.gitignore +2/−0
- examples/hxpath/HXPath.hs +152/−0
- examples/hxpath/Makefile +59/−0
- examples/hxpath/W3CTestData.hs +1079/−0
- examples/hxpath/XPathShell.hs +178/−0
- examples/hxpath/example1.xml +27/−0
- examples/hxpath/xhtml/xhtml-lat1.ent +196/−0
- examples/hxpath/xhtml/xhtml-special.ent +79/−0
- examples/hxpath/xhtml/xhtml-symbol.ent +242/−0
- examples/hxpath/xhtml/xhtml.xml +1484/−0
- examples/hxpath/xhtml/xhtml1-frameset.dtd +1225/−0
- examples/hxpath/xhtml/xhtml1-strict.dtd +988/−0
- examples/hxpath/xhtml/xhtml1-transitional.dtd +1196/−0
- hxt-xpath.cabal +62/−0
- src/Text/XML/HXT/XPath.hs +19/−0
- src/Text/XML/HXT/XPath/Arrows.hs +292/−0
- src/Text/XML/HXT/XPath/NavTree.hs +194/−0
- src/Text/XML/HXT/XPath/XPathArithmetic.hs +166/−0
- src/Text/XML/HXT/XPath/XPathDataTypes.hs +354/−0
- src/Text/XML/HXT/XPath/XPathEval.hs +631/−0
- src/Text/XML/HXT/XPath/XPathFct.hs +864/−0
- src/Text/XML/HXT/XPath/XPathKeywords.hs +57/−0
- src/Text/XML/HXT/XPath/XPathParser.hs +652/−0
- src/Text/XML/HXT/XPath/XPathToNodeSet.hs +67/−0
- src/Text/XML/HXT/XPath/XPathToString.hs +135/−0
+ LICENCE view
@@ -0,0 +1,9 @@+The MIT License++Copyright (c) 2005 Uwe Schmidt, Martin Schmidt, Torben Kuseler++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.
+ Setup.lhs view
@@ -0,0 +1,8 @@+#!/usr/bin/runhaskell++> module Main where++> import Distribution.Simple++> main :: IO ()+> main = defaultMain
+ examples/Makefile view
@@ -0,0 +1,17 @@+# Example Applications+#++EXAMPLES = hunit hxpath+MORE_SAMPLES = ++all :+ $(foreach i,$(EXAMPLES),$(MAKE) -C $i all ;)++test :+ $(foreach i,$(EXAMPLES),$(MAKE) -C $i $@ ;)++clean :+ $(foreach i,$(EXAMPLES),$(MAKE) -C $i $@ ;)++.PHONY : all test clean+
+ examples/hunit/HUnitExample.hs view
@@ -0,0 +1,106 @@+-- |+-- HUnit - Haskell XML Toolbox examples and tests for arrows+--+-- Author: Uwe Schmidt uwe@fh-wedel.de+--++module Main where++import System+import Test.HUnit+import Text.XML.HXT.Arrow+import Text.XML.HXT.XPath+++-- |+-- auxiliary function to make haskell string constants with quotes more readable++singleToDoubleQuote :: String -> String+singleToDoubleQuote+ = map (\ c -> if c == '\'' then '\"' else c)++testLA :: String -> String -> LA XmlTree XmlTree -> Test+testLA doc expected f+ = TestCase $ assertEqual "LA XmlTree XmlTree:" [expected] res+ where+ res = runLA (xread >>> xshow f) doc++testLAString :: String -> String -> LA XmlTree String -> Test+testLAString doc expected f+ = TestCase $ assertEqual "LA XmlTree String:" [expected] res+ where+ res = runLA (xread >>> f) doc++mkTestSeqLA :: String -> [(String, LA XmlTree XmlTree)] -> [Test]+mkTestSeqLA doc+ = map (\ (res, f) -> testLA doc (singleToDoubleQuote res) f)++nodeSetTests :: Test+nodeSetTests+ = TestList $+ [ TestLabel "node set and simple XPath tests with getXPathTrees" $+ TestList $+ mkTestSeqLA doc (testGetXPathTrees tests)++ , TestLabel "node set and simple XPath tests with getXPathNodeSet" $+ TestList $+ mkTestSeqLA doc (testGetXPathNodes tests)++ , TestLabel "node set and simple XPath tests with processFromNodeSet" $+ TestList $+ mkTestSeqLA doc (testProcessXPath processTests)++ , TestLabel "node set and simple XPath tests with processXPathTrees" $+ TestList $+ mkTestSeqLA doc (testProcessXPath' processTests)+ ]+ where+ doc = "<x p='.'>.0<x p='.1'>.1.0</x>.2<y p='.3'>.3.0<x p='.3.1'>.3.1.0</x></y>.4</x>"++ testGetXPathTrees = map (\ (r, xp) -> (r, getXPathTrees xp)) -- these arrows are equivalent+ testGetXPathNodes = map (\ (r, xp) -> (r, getFromNodeSet $< getXPathNodeSet xp)) -- except for the ordering of the result set+ -- which does not matter for these tests+ testProcessXPath = map (\ (r, xp, a) -> (r, processFromNodeSet a $< getXPathNodeSet xp))+ testProcessXPath' = map (\ (r, xp, a) -> (r, processXPathTrees a xp))++ tests = [ (doc , "/x" )+ , ("<y p='.3'>.3.0<x p='.3.1'>.3.1.0</x></y>" , "/x/y" )+ , ("<x p='.3.1'>.3.1.0</x>" , "/x/y/x" )+ , (".0.2.4" , "/x/text()" )+ , (".3.0" , "/x/y/text()" )+ , ("<x p='.1'>.1.0</x><x p='.3.1'>.3.1.0</x>" , "/x//x" )+ ]++ processTests+ = [ ("<x p='.'>x<x p='.1'>x</x>x<y p='.3'>x<x p='.3.1'>x</x></y>x</x>", "//text()", changeText (const "x") )+ , ("<x p='.'>.0<x p='.1'>.1.0</x>.2<y p='.3'>.3.0<x p='.3.1'>x</x></y>.4</x>", "/x/y/x/text()", changeText (const "x") )+ , ("<x p='.'>.0<x p='.1'>.1.0</x>.2<y p='.3'>.3.0</y>.4</x>", "/x/y/x", none )+ , ("<x p='.'>.0<x p='.1'>.1.0</x>.2<y p='.3'>.3.0zzz</y>.4</x>", "/x/y/x", txt "zzz" )+ , ("<x p='.'>.0<x p='.1'>.1.0</x>.2<y p='.3'>.3.0<x p='.3.1' q='3.2'>.3.1.0</x></y>.4</x>",+ "/x/y/x", addAttr "q" "3.2" )+ ]+-- |+-- the complete set of test cases++allTests :: Test+allTests+ = TestList+ [ nodeSetTests+ ]++main :: IO ()+main+ = do+ c <- runTestTT allTests+ putStrLn $ show c+ let errs = errors c+ fails = failures c+ System.exitWith (codeGet errs fails)++codeGet :: Int -> Int -> ExitCode+codeGet errs fails+ | fails > 0 = ExitFailure 2+ | errs > 0 = ExitFailure 1+ | otherwise = ExitSuccess++-- ----------------------------------------------------------
+ examples/hunit/Makefile view
@@ -0,0 +1,32 @@+# $Id: Makefile,v 1.2 2006/05/11 14:47:18 hxml Exp $++HXT_HOME = ../../..+PKGFLAGS =+GHCFLAGS = -Wall -O2+GHC = ghc $(GHCFLAGS) $(PKGFLAGS)++prog = HUnitExample++all : $(prog)++force :+ $(GHC) --make $(GHCPACKAGES) -o $(prog) $(prog).hs++$(prog) : $(prog).hs+ $(GHC) --make $(GHCPACKAGES) -o $@ $<++test : $(prog)+ @echo "===> run HUnit examples" ; echo ; sleep 2+ ./$(prog)++DIST = $(HXT_HOME)/dist/examples/arrows+DIST_DIR = $(DIST)/hunit+DIST_FILES = mini1.xml mini2.xml Makefile $(prog).hs++dist :+ [ -d $(DIST_DIR) ] || mkdir -p $(DIST_DIR)+ cp $(DIST_FILES) $(DIST_DIR)++clean :+ rm -f $(prog) $(prog).o $(prog).hi+
+ examples/hunit/mini1.xml view
@@ -0,0 +1,1 @@+<x/>
+ examples/hunit/mini2.xml view
@@ -0,0 +1,1 @@+<data> <data class="data">ignore</data> <data class="meta">unknown</data> <data><data class="data">important</data> <data class="meta">important</data></data> </data>
+ examples/hxpath/.ghci view
@@ -0,0 +1,4 @@+:set -package-conf ../../../lib/hxt/package.conf+:set -package hxt+:set -Wall+:load HXPath
+ examples/hxpath/.gitignore view
@@ -0,0 +1,2 @@+HXPath+XPathShell
+ examples/hxpath/HXPath.hs view
@@ -0,0 +1,152 @@+-- ------------------------------------------------------------++{- |+ Module : HXPath+ Copyright : Copyright (C) 2005 Torbel Kuseler, Uwe Schmidt+ License : MIT++ Maintainer : Uwe Schmidt+ Maintainer : uwe@fh-wedel.de+ Stability : experimental+ Portability: portable+ Version : $Id: HXPath.hs,v 1.2 2006/05/11 14:47:18 hxml Exp $++HXPath - XPath Evaluator of the Haskell XML Toolbox (Arrow version)++-}++-- ------------------------------------------------------------++module Main+where++import Text.XML.HXT.Arrow+import Text.XML.HXT.XPath++import System.IO -- import the IO and commandline option stuff+import System.Environment+import System.Console.GetOpt+import System.Exit++import Data.Maybe++-- ------------------------------------------------------------++-- |+-- the main program++main :: IO ()+main+ = do+ argv <- getArgs -- get the commandline arguments+ (al, expr, src) <- cmdlineOpts argv -- and evaluate them, return a key-value list+ [rc] <- runX (xpath al expr src) -- run the parser arrow+ exitProg (rc >= c_err) -- set return code and terminate++-- ------------------------------------------------------------++exitProg :: Bool -> IO a+exitProg True = exitWith (ExitFailure (-1))+exitProg False = exitWith ExitSuccess++-- ------------------------------------------------------------++-- |+-- the /real/ main program+--+-- runs in the trivial XmlState monad (with user state set to ())+-- so IO and access to global options is possible++xpath :: Attributes -> String -> String -> IOSArrow b Int+xpath al expr src+ = readDocument al src+ >>>+ evalXPathExpr+ >>>+ traceMsg 1 "evaluation finished"+ >>>+ traceSource+ >>>+ traceTree+ >>>+ formatXPathResult+ >>>+ writeDocument al "-"+ >>>+ getErrStatus+ where+ evalXPathExpr :: IOSArrow XmlTree XmlTree+ evalXPathExpr+ = traceMsg 1 ("evaluating XPath expression: " ++ expr)+ >>>+ replaceChildren ( getXPathTreesInDoc expr+ >>>+ filterErrorMsg+ )++ formatXPathResult :: IOSArrow XmlTree XmlTree+ formatXPathResult+ = replaceChildren ( mkelem "xpath-result"+ [ sattr "expr" expr, sattr "source" src ]+ [ newline, getChildren >>> (this <+> newline) ]+ )+ where+ newline+ | isJust . lookup a_indent $ al = txt "\n"+ | otherwise = none++-- ------------------------------------------------------------+--+-- the options definition part+-- see doc for System.Console.GetOpt++progName :: String+progName = "HXPath"+ +options :: [OptDescr (String, String)]+options+ = generalOptions+ +++ inputOptions+ +++ outputOptions++usage :: [String] -> IO a+usage errl+ | null errl+ = do+ hPutStrLn stdout use+ exitProg False+ | otherwise+ = do+ hPutStrLn stderr (concat errl ++ "\n" ++ use)+ exitProg True+ where+ header = "HXPath - XPath Evaluator of the Haskell XML Toolbox (Arrow Version)\n" +++ "Usage: " ++ progName ++ " [OPTION...] <XPath expr> <URL or FILE>"+ use = usageInfo header options++cmdlineOpts :: [String] -> IO (Attributes, String, String)+cmdlineOpts argv+ = case (getOpt Permute options argv) of+ (ol,n,[] )+ -> do+ (ex, sa) <- src n+ help (lookup a_help ol)+ return (ol, ex, sa)+ (_,_,errs)+ -> usage errs+ where+ src [expr, url]+ = return (expr, url)+ src []+ = usage ["XPath expression and input file/url missing"]+ src [_]+ = usage ["input file/url missing"]+ src _+ = usage ["too many arguments"]++ help Nothing = return ()+ help (Just _) = usage []++-- ------------------------------------------------------------
+ examples/hxpath/Makefile view
@@ -0,0 +1,59 @@+# $Id: Makefile,v 1.2 2005/04/14 12:52:51 hxml Exp $++HXT_HOME = ../../..+PKGFLAGS = +GHCFLAGS = -Wall -O2+GHC = ghc $(GHCFLAGS) $(PKGFLAGS)++prog = ./HXPath+prog2 = ./XPathShell++all : $(prog) $(prog2)++force :+ $(GHC) --make -o $(prog) $(prog).hs++local :+ ghc --make -o $(prog2) $(GHCFLAGS) -fglasgow-exts -ignore-package hxt -i../../../src $(prog2).hs++$(prog) : $(prog).hs+ $(GHC) --make -o $@ $<++$(prog2) : $(prog2).hs+ $(GHC) --make -o $@ $<++EX = xhtml/xhtml.xml++test : $(prog)+ @echo "===> XPath extraction examples" ; echo ; sleep 2+ @$(MAKE) test1 test2 test3 test4++test1 :+ @echo "===> extract all text from the XHTML document" ; echo ; sleep 2+ $(prog) --do-not-validate "/html/body/descendant-or-self::text()" $(EX)+ @echo++test2 :+ @echo "===> extract the 42. paragraph from the XHTML document" ; echo ; sleep 2+ $(prog) --do-not-validate "/descendant::p[position()=42]" $(EX)+ @echo++test3 :+ @echo "===> extract the text of all top level h1 tags from the XHTML document" ; echo ; sleep 2+ $(prog) --indent --do-not-validate "/child::html/child::body/child::h1/descendant-or-self::text()" $(EX)+ @echo++test4 :+ @echo "===> extract all href attributes from a tags from the XHTML document" ; echo ; sleep 2+ $(prog) --indent --do-not-validate "/descendant::a/attribute::href" $(EX)+ @echo++DIST = $(HXT_HOME)/dist/examples/arrows+DIST_DIR = $(DIST)/hxpath++dist :+ [ -d $(DIST_DIR) ] || mkdir -p $(DIST_DIR)+ cp Makefile $(prog).hs $(prog2).hs $(DIST_DIR)++clean :+ rm -f $(prog) *.hi *.o
+ examples/hxpath/W3CTestData.hs view
@@ -0,0 +1,1079 @@+module W3CTestData where++testListW3C=[+ "$h - $i",+ "$hotelnode/location/@country",+ "$in//text()",+ "$l10n.name",+ "$lookup/@text",+ "$start + $step",+ "$texts[position() > 1]",+ "$var1|$var2",+ "$var1|child::child2",+ "$var1|key('key1','Lynne Rosenthal')",+ "$x=''",+ "$x='foo'",+ "$xml-source",+ "$y='foo'",+ "$zoo:bear",+ "' #text'",+ "' 6 ' div 2",+ "' 6 '*div",+ "' x 4'",+ "' x 4'",+ "'....5....|'",+ "'1' and '0'",+ "'2'>'1'",+ "'200'",+ "'ABC'",+ "($terms/table/expand[@language=$lang]/gentext[@key=$key])[1]",+ "((((((n3+5)*(3)+(((n2)+2)*(n1 - 6)))-(n4 - n2))+(-(4-6)))))",+ "(((ancestor::foo)[1])/@att1)",+ "((ancestor::foo))[1]/@att1",+ "(* - 4) div 2",+ "(* - 4)**",+ "(2 + number('xxx'))",+ "(24 div 3 +2) div (40 div 8 -3)",+ "(5 mod 2 = 1) and (5 mod -2 = 1) and (-5 mod 2 = -1) and (-5 mod -2 = -1)",+ "(77 mod $anum + n5 mod 8) mod $anum",+ "(ancestor-or-self::*)[@att1][1]/@att1",+ "(ancestor::foo)[1]/@att1",+ "(ancestor::foo[1])/@att1",+ "(ancestor::section|ancestor::simplesect |ancestor::articleinfo)[last()]",+ "(chapter//footnote)[2]",+ "(child::chapter/descendant-or-self::node())/footnote[2]",+ "(n1*n2*n3*n4*n5*n6)div n7 div n8 div n9 div n10",+ "(n1/@attrib)*(n2/@attrib)",+ "(n1/@attrib)+(n2/@attrib)",+ "(preceding-sibling::*|following-sibling::*)/ancestor::*[last()]/*[last()]",+ "(preceding-sibling::foo)[1]/@att1",+ "(preceding::foo)[1]/@att1",+ "(section//@title)[7]",+ "(xalan:nodeset($rtf)/default:docelem/test:elem3)", -- namespaces noch mal ueberdenken+ "* +3",+ "*//la | //Bflat | re",+ "*/p",+ "*[$index]",+ "*[$index]",+ "*[$index]",+ "*[1]",+ "*[3]",+ "*[4]",+ "*[@test and position()=1]",+ "*[@test and position()=4]",+ "*[@test and position()=7]",+ "*[@test and position()=8]",+ "*[@test='true']",+ "*[@test][1]/num",+ "*[@test][position()=1]/num",+ "*[last()=position()]",+ "*[last()]",+ "*[local-name()='bar']",+ "*[not(@test)][last()=position()]",+ "*[not(@test)][last()]",+ "*[position()=1]",+ "*[position()=3]",+ "*[position()=4]",+ "*[starts-with(name(.),'f')]",+ "*|@*",+ "*|@*|comment()|processing-instruction()|text()",+ "-(n-2/@attrib) - -(n-1/@attrib)",+ "-(n1|n2)",+ "-.0000000000000000000000000000000000000000123456789",+ "-.01",+ "-n-2 --n-1",+ "-n-2/@attrib --n-1/@attrib",+ "..",+ "../../a/b[1]",+ "..//foo",+ "../@id",+ "../node()",+ "./*[name(.) = $sortcol]",+ ".//*[@so]",+ ".//PERSONA",+ ".//a",+ ".//center",+ ".//center",+ ".//comment()",+ ".//f",+ ".//near-south/preceding-sibling::*|following-sibling::east/ancestor-or-self::*[2]",+ ".//text()",+ ".//title",+ "./@id",+ "./@theattrib",+ ".0000000000000000000000000000000000000000123456789",+ ".01",+ ".123456789",+ "/", + "/*/@group",+ "//*",+ "//*",+ "//*[count(./*/*) > 0]",+ "//*[count(ancestor::*) >= 2]/../parent::*",+ "//ACT",+ "//ancestor::*",+ "//child1[parent::element1]",+ "//child1|//child2",+ "//child2[ancestor-or-self::element2]",+ "//child2[ancestor::element2]",+ "//child5|//child2|//child4",+ "//comment()",+ "//inc/node4",+ "//item[@type=current()/@name]",+ "//noChild1|//noChild2",+ "//north/dup2 | south/preceding-sibling[4] | north/dup1 | north/*",+ "//processing-instruction()",+ "//xx/descendant::*",+ "/doc/*[@test='true']",+ "/doc/a/b/@attr",+ "/doc/critter[@type='cat']",+ "/doc/mid/inner",+ "/doc/sub1/child1|/doc/sub2/child2",+ "/docs/a",+ "/docs/a",+ "/page/contents/avail/hotel",+ "/sss/sss/i",+ "/sss/sss/i",+ "0 > -0",+ "0 = -0",+ "0 div 0 >= 0",+ "0 div 0 < 0",+ "0 div 0",+ "0 or ''",+ "0",+ "0000000000",+ "1 = '001'",+ "1 = 1.00",+ "1 div -0 = 1 div 0",+ "1 div -0 = 2 div -0",+ "1>1",+ "1<1",+ "1<=1",+ "1-2",+ "10+5+25+20+15+50+35+40",+ "10+7",+ "100-$anum -5-15-$anum",+ "100-9-7-4-17-18-5",+ "100-n6 -4-n1 -1-11",+ "12",+ "123",+ "1234",+ "12345",+ "123456",+ "1234567",+ "12345678",+ "123456789",+ "1234567890",+ "12345678901",+ "123456789012",+ "1234567890123",+ "12345678901234",+ "123456789012345",+ "1234567890123456",+ "12345678901234567",+ "123456789012345678",+ "16-div",+ "1=1",+ "2 * -number('xxx')",+ "2 - number('xxx')",+ "2 div number('xxx')",+ "2 mod number('xxx')",+ "2",+ "2>1",+ "2>=1",+ "2>=2",+ "2<1",+ "2<=1",+ "2*3",+ "2+n5+7+n3",+ "20",+ "25-*",+ "256",+ "3",+ "3",+ "3*2+5*4-4*2-1",+ "3+6",+ "3-1",+ "32",+ "4",+ "4",+ "444 + $t1num",+ "48 mod 17 - 2 mod 9 + 13 mod 5",+ "5 mod 2",+ "5",+ "5",+ "5.*.",+ "5.+*",+ "54 div*",+ "555",+ "56 mod round(n5*2+1.444) - n6 mod 4 + 7 mod n4",+ "6 div -2",+ "6 div 2",+ "6",+ "60",+ "7 - -3",+ "7",+ "7",+ "7+-3",+ "70 div $anum - 18 div n6 + $anum div n2",+ "8",+ "80 div n2 + 12 div 2 - n4 div n2",+ "9",+ "9.87654321012345",+ "98.7654321012345",+ "987.654321012345",+ "9876.54321012345",+ "98765.4321012345",+ "987654.321012345",+ "9876543.21012345",+ "98765432.1012345",+ "987654321.012345",+ "9876543210",+ "9876543210.12345",+ "98765432101.2345",+ "987654321012.345",+ "9876543210123.45",+ "98765432101234.5",+ "FM|PERSONAE|ACT",+ "Name/@First",+ "OL",+ "Personal_Information/Age",+ "Spr/State[. = 'Open']",+ "a/*[last()]",+ "a/child::*[last()]",+ "a/child::comment()[last()]",+ "a/child::node()[last()]",+ "a/child::text()[last()]",+ "a/descendant::*[last()]",+ "a/x",+ "a['3.5' < 4]",+ "a['target'!=descendant::*]",+ "a['target'=descendant::*]",+ "a[('target'=descendant::*) or @squish]",+ "a[(@squeesh or @squish) and @squash]",+ "a[*=9]",+ "a[0 < true()]",+ "a[0]",+ "a[1 < 2]",+ "a[1 < 3]",+ "a[1]",+ "a[3 > following-sibling::*]",+ "a[3 >= following-sibling::*]",+ "a[3 < following-sibling::*]",+ "a[3 <= following-sibling::*]",+ "a[3-2]",+ "a[3.0='3.0']",+ "a[3=following-sibling::*]",+ "a[3]",+ "a[4 != following-sibling::*]",+ "a[4]",+ "a[@squeesh or (@squish and @squash)]",+ "a[@squeesh or @squish and @squash]",+ "a[descendant::*!='target']",+ "a[descendant::*='target']",+ "a[div=9]",+ "a[false()!=following-sibling::*]",+ "a[following-sibling::* != 4]",+ "a[following-sibling::* > 3]",+ "a[following-sibling::* >= 3]",+ "a[following-sibling::* < 3]",+ "a[following-sibling::* <= 3]",+ "a[following-sibling::*!=false()]",+ "a[following-sibling::*=3]",+ "a[following-sibling::*=descendant::*]",+ "a[following-sibling::*=true()]",+ "a[not(('target'=descendant::*) or @squish)]",+ "a[not(@*)]",+ "a[number('3')]",+ "a[position() <=3]",+ "a[position()!=2]",+ "a[position()>2]",+ "a[position()>=2]",+ "a[position()<3]",+ "a[position()=$first]",+ "a[position()=1]",+ "a[position()=3]",+ "a[position()=4]",+ "a[true()='stringwithchars']",+ "a[true()=4]",+ "a[true()=following-sibling::*]",+ "alternate/name/first",+ "ancestor-or-self::*",+ "ancestor-or-self::*[1]",+ "ancestor-or-self::*[1]/text()",+ "ancestor-or-self::*[@att1][1]/@att1",+ "ancestor-or-self::sub | ancestor-or-self::sub-sub",+ "ancestor::*",+ "ancestor::*[3]",+ "ancestor::*[count(child::*) > 1]/*[not(. = current()/ancestor-or-self::*)]",+ "ancestor::foo[1]/@att1",+ "ancestor::sub1|ancestor::sub2",+ "attribute :: *",+ "attribute :: div",+ "attribute*(div - 4)",+ "attribute::*",+ "attribute::*[2]",+ "attribute::attr1|attribute::attr2",+ "attribute::center-attr-2",+ "author/name|author/bibliography/author/chapters",+ "author/name|author/bibliography/author/name",+ "author/name|author/noElement",+ "author[(name/@real='no' and position()=1)]|author[(name/@real='yes' and position()=last())]",+ "author[name/@real='no']|author[name/@real='yes']",+ "author[name='Mary Brady']|author[name/@real='no']",+ "bar | joes:bar",+ "bar[(@a='1' and @b='1') or (@c='1' and @d='1')]",+ "bar[(@a='1' or @b='1') and (@c='1' or @d='1')]",+ "bar[(@a='1' or @b='1') and @c='1']",+ "bar[@a='1' and (@b='1' or @c='1') and @d='1']",+ "bar[@a='1' and @b='1' or @c='1' and @d='1']",+ "bar[@a='1' and @b='1']",+ "bar[@a='1' or (@b='1' and @c='1') or @d='1']",+ "bar[@a='1' or @b='1' and @c='1' or @d='1']",+ "bar[@a='1' or @b='1' or @c='1']",+ "boolean($ResultTreeFragTest)",+ "boolean($emptyResultTreeFragTest)",+ "boolean('')",+ "boolean('0')",+ "boolean(-0)",+ "boolean(0 div 0)",+ "boolean(0)",+ "boolean(1 div 0)",+ "boolean(1)",+ "boolean(doc)",+ "boolean(foo)",+ "ceiling(-1.5)=-1",+ "ceiling(0.0)",+ "ceiling(1)=1",+ "ceiling(1.1)=2",+ "ceiling(1.54)",+ "ceiling(2.999999)",+ "ceiling(n0)",+ "ceiling(n1)",+ "ceiling(n2)",+ "ceiling(number('xxx'))",+ "center//*",+ "center//child::*",+ "center//descendant::*",+ "center/child::*",+ "center/descendant::*",+ "chapter//footnote[1]",+ "chapter//footnote[2]",+ "chapter/descendant::footnote[6]",+ "chapter/note",+ "chapter/note",+ "child :: sub",+ "child1[child::child2]",+ "child::*",+ "child::*/child::*",+ "child::*/descendant::*",+ "child::*[2]",+ "child::article|key('key1','Carmelo Montanez')",+ "child::near-south-west",+ "child::node()",+ "child::sub",+ "child::sub1|child::sub2",+ "child[@deep='3']|child[@wide='3']",+ "child[@wide='3'] | key('one','3')",+ "child[@wide='3']|child[@deep='3']",+ "chooser",+ "comment ()",+ "concat( substring(subj,1,number(not(starts-with(.,'Re: ')))*string-length(subj)), substring(substring-after(subj,'Re: '),1, number(starts-with(.,'Re: '))*string-length(substring-after(subj,'Re: '))))",+ "concat($act,' - ',TITLE,' ')",+ "concat($mParam,$nParam,$oParam,$pParam)",+ "concat($str,'....5....|')",+ "concat('id=', string($p2))",+ "concat(/*, /*[@attr='whatsup'])",+ "concat(a, 34)",+ "concat(a, b)",+ "concat(a, b, c, d, e)",+ "concat(false(),'ly')",+ "concat(left,right,orig)",+ "concat(left,right,orig)",+ "concat(team[1], ' versus ', team[2])",+ "concat(team[1]/@score, '-', team[2]/@score)",+ "contains( unparsed-entity-uri('hatch-pic'),'grafix/OpenHatch.gif')",+ "contains($node,$find)",+ "contains('','')",+ "contains('ENCYCLOPEDIA', 'CYCL')",+ "contains('ENCYCLOPEDIA', 'TEST')",+ "contains('ab', 'abc')",+ "contains('abc', '')",+ "contains('abc', 'bc')",+ "contains('abc', 'bcd')",+ "contains('foo','o')",+ "contains('true()', 'e')",+ "contains(., '&')",+ "contains(concat(.,'BC'),concat('A','B','C'))",+ "contains(doc, 'CYCL')",+ "contains(doc, 'TEST')",+ "contains(doc/@attr, 'TEST')",+ "contains(doc/@attr, 'amwi')",+ "contains(main,sub)",+ "contains(main,sub)",+ "contains(main,sub)",+ "contains(main,sub)",+ "count($var1)",+ "count($var2)",+ "count(*)",+ "count(*)",+ "count(*/z[2])",+ "count(.//SPEECH)",+ "count(.//comment())",+ "count(/doc/alpha[last()]/h)",+ "count(/doc/chapter/note)",+ "count(a/@*)",+ "count(a/attribute::*)",+ "count(alpha/*[last()][name()='z'])",+ "count(ancestor::section |../ednote|following::title|../bogus)",+ "count(ancestor::section |ancestor::simplesect|ancestor::article)",+ "count(ancestor::section |ancestor::simplesect|ancestor::articleinfo)",+ "count(div)",+ "count(following-sibling::*)",+ "count(key('mykey', 'Introduction'))",+ "count(namespace::*)",+ "count(preceding::text())",+ "count(preceding::text())",+ "count(xalan:nodeset($rtf)/default:docelem/default:elem3)",+ "counter:read('index')",+ "counter:read('index')",+ "critter",+ "critter",+ "current()",+ "current()",+ "current()",+ "customers/customer",+ "d",+ "dat",+ "date",+ "date:getYear()",+ "day",+ "day",+ "day",+ "day",+ "day",+ "descendant-or-self::*",+ "descendant-or-self::*",+ "descendant-or-self::*[3]",+ "descendant-or-self::center",+ "descendant-or-self::far-south",+ "descendant-or-self::sub1|descendant-or-self::sub2",+ "descendant::*",+ "descendant::*",+ "descendant::*/child::*",+ "descendant::*[3]",+ "descendant::*[string-length(name(.))=1]",+ "descendant::child1|descendant::child2",+ "descendant::far-south",+ "display",+ "display",+ "display",+ "div +3",+ "div div mod",+ "div mod mod",+ "div",+ "div/@attrib div mod/@attrib",+ "div/@attrib mod mod/@attrib",+ "div/para[lang('en')]",+ "doc/element1[2]/child1[last()]",+ "document($typefile,/)",+ "document('')/*/xsl:template[@name=$whichtmplt]",+ "document('')/*/xsl:template[@name=$whichtmplt]",+ "document('')/*/xsl:template[@name='qq']/node()",+ "document('')/xsl:stylesheet/ped:test[@attrib='yeha']",+ "document('')/xsl:stylesheet/ped:test[@attrib='yeha']",+ "document('../impincl-test/mdocs11a.xml')//body",+-- "document('..\mdocs\compu.xml')/market.participant/address.set/*", -- \ mag er nicht+ "document('bib.xml')",+ "document('level3/xreluri09a.xml',document('level1/level2/xreluri09b.xml'))",+ "document('mdocs01a.xml')//body",+ "document('mdocs03a.xml',section)",+ "document('select68.xml')//inside",+ "document('select68.xml')//inside",+ "document('terms.xml')",+ "document('variable20.xml')",+ "document('x14template.html')",+ "document(a)//body",+ "document(a)//body",+ "document(a)//body",+ "document(document(places))",+ "document(filename,document('level1/level2/xreluri10b.xml'))/*/body",+ "document(places)",+ "document(places)//body",+ "document(places,second)/*",+ "document(pointer/urlref/@urlstr)/market.participant/business.identity.group/business.name",+ "element",+ "element1[(((((2*10)-4)+9) div 5) mod 3 )]",+ "element1[(((((2*10)-4)+9) div 5) mod floor(3))]",+ "element1[descendant-or-self::child2]",+ "element1[floor(2)]",+ "em:foo",+ "expense-report/total",+ "expense-report/total",+ "ext:getPIData(doc/processing-instruction('a-pi'))",+ "extn1:getPIData(doc/processing-instruction('a-pi')[1])",+ "extn1:getPIData(doc/processing-instruction('b-pi'))",+ "fa/../mi | Aflat/natural/la | Csharp//* | /doc/do | *//ti",+ "false() and 1 div 0",+ "false() and false()",+ "false() and true()",+ "false() or false()",+ "false() or true()",+ "false()",+ "false()=''",+ "false()=0",+ "floor(-1.5)",+ "floor(-1.5)=-2",+ "floor(0.0)",+ "floor(1)=1",+ "floor(1.9)",+ "floor(1.9)=1",+ "floor(2.999999)",+ "floor(n0)",+ "floor(number('xxx'))",+ "following-sibling::*",+ "following-sibling::*/preceding-sibling::*",+ "following-sibling::*[1]",+ "following-sibling::*[2]/preceding-sibling::*",+ "following-sibling::*[2]/preceding-sibling::*[4]",+ "following-sibling::*[2]/preceding-sibling::*[4]/following-sibling::*[5]/preceding-sibling::*[4]/preceding-sibling::*[2]",+ "following-sibling::east",+ "following-sibling::node()",+ "following::*",+ "following::*[4]",+ "following::*[4]/../*[2]",+ "foo[(bar[2])='this']",+ "foo[(bar[2][(baz[2])='goodbye'])]",+ "format-number('foo','#############')",+ "format-number('foo','#############')",+ "format-number(-1 div 0,'###############################')",+ "format-number(-1 div 0,'###############################')",+ "format-number(-26931.4,'!!!,!!!.!!!')",+ "format-number(-26931.4,'###,###.###')",+ "format-number(-26931.4,'###,###.###','myminus')",+ "format-number(-26931.4,'###,###.###;###,###.###')",+ "format-number(-26931.4,'###.###,###','periodgroup')",+ "format-number(-26931.4,'###.###,###','periodgroup')",+ "format-number(-26931.4,'###.###,###','periodgroup')",+ "format-number(-26931.4,'###.###,###','periodgroup')",+-- "format-number(-26931.4,'+!!,!!!.!!!\-!!!,!!!.!!!')", -- vom W3C auskommentiert+ "format-number(-26931.4,'+###,###.###;-###,###.###')",+ "format-number(-26931.4,'+###,###.###;_###,###.###')",+ "format-number(-26931.4,'-###,###.###')",+ "format-number(-26931.4,'-###,###.###','myminus')",+ "format-number(-26931.4,'_###,###.###','myminus')",+ "format-number(-42857.1,'###,###.###')",+ "format-number(-42857.1,'###,###.###','myminus')",+ "format-number(-42857.1,'###,###.###','myminus')",+ "format-number(-42857.1,'###,###.###','newminus')",+ "format-number(-42857.1,'###,###.###','newminus')",+ "format-number(-73816.9,'###,###.###')",+ "format-number(-73816.9,'###,###.###')",+ "format-number(-73816.9,'###,###.###')",+ "format-number(-73816.9,'###,###.###')",+ "format-number(0.25, '00%')",+ "format-number(0.4857,'###.###%')",+ "format-number(0.4857,'###.###c')",+ "format-number(0.4857,'###.###m')",+ "format-number(0.4857,'###.###‰')",+ "format-number(1 div 0,'###############################')",+ "format-number(1 div 0,'###############################')",+ "format-number(1, '#,##0')",+ "format-number(1, '00')",+ "format-number(1, '00.0')",+ "format-number(1000, '###0')",+ "format-number(1234.567,'#*###*###!###','foo:decimal1')",+ "format-number(12792.14*96.58,'##,###,000.000###')",+ "format-number(2.14*86.58,'PREFIX##00.000###SUFFIX')",+ "format-number(2392.14*(-36.58),'000,000.000###;###,###.000###')",+ "format-number(2392.14*(-36.58),'000,000.000###;-###,###.000###')",+ "format-number(2392.14*36.58,'000,000.000000')",+ "format-number(2392.14*36.58,'000,000.000000','myminus')",+ "format-number(2392.14*36.58,'000,000.000000;###,###.000###')",+ "format-number(2392.14*36.58,'000,000.000000;###,###.000###','myminus')",+ "format-number(239236.588,'00000.00')",+-- "format-number(26931.4,'+!!!,!!!.!!!\-!!,!!!.!!!')", -- vom W3C auskommentiert+ "format-number(2792.14*(-36.58),'000,000.000###')",+ "format-number(4030201.0506,'#!!!,!!!,aaa.aaaaaa0')",+ "format-number(7654321.4857,'### ### ###,#####')",+ "format-number(931.4857,'###!###!###')",+ "format-number(931.4857,'000.000|###')",+ "format-number(95.4857,'¤###.####')",+ "format-number(987654321,'###,##0,00.00')",+ "generate-id(d)",+ "generate-id(xalan:nodeset($rtf)/default:docelem/default:elem4)",+ "growth",+ "growth",+ "human",+ "id('c')/@id",+ "id('c')/@id",+ "id('d b c')",+ "id('id0')/a/b",+ "id('id0')/c/c/a",+ "id('id10')/a",+ "id('id13')",+ "id('id2')/a | id('id5') | id('id15')/a",+ "id('id4')",+ "id('id8')/b/b",+ "id('id9')",+ "id('nomatch')/@id",+ "id(main/b)",+ "id(main/b)",+ "item[$n1]",+ "item[position()=$n]",+ "java:format($formatter, $date)",+ "java:format($formatter, $javadate)",+ "java:get ($counter-table, 'index')",+ "java:java.lang.Long.parseLong(string(.))",+ "java:java.text.SimpleDateFormat.new('yyyy.MM.dd hh:mm')",+ "java:java.util.Calendar.getInstance()",+ "java:java.util.Date.new($date)",+ "java:java.util.Hashtable.new ()",+ "key($keysp, 'Expressions')/subdiv/p",+ "key($keysp, 'Introduction')/subdiv/p",+ "key($keysp, 'Stylesheet Structure')/subdiv/p",+ "key('MonthNum',month)",+ "key('MonthNum',month)",+ "key('baz:mykey', 'Expressions')/p",+ "key('baz:mykey', 'Introduction')/p",+ "key('baz:mykey', 'Stylesheet Structure')/p",+ "key('bib',$lookup)",+ "key('bigspace', 'Expressions')/subdiv/p",+ "key('bigspace', 'Expressions')/subdiv/p",+ "key('bigspace', 'Introduction')/subdiv/p",+ "key('bigspace', 'Introduction')/subdiv/p",+ "key('bigspace', 'Stylesheet Structure')/subdiv/p",+ "key('bigspace', 'Stylesheet Structure')/subdiv/p",+ "key('filterspace', 'Expressions')/subdiv/p",+ "key('filterspace', 'Expressions')/subdiv/p",+ "key('filterspace', 'Introduction')/subdiv/p",+ "key('filterspace', 'Introduction')/subdiv/p",+ "key('filterspace', 'Stylesheet Structure')/subdiv/p",+ "key('filterspace', 'Stylesheet Structure')/subdiv/p",+ "key('k','Albany')",+ "key('k','Albany')",+ "key('k','false')[position()=1]/num",+ "key('k','false')[position()=2]/num",+ "key('k','true')[1]/num",+ "key('k','true')[1]/num",+ "key('k','true')[3]/num",+ "key('k','true')[3]/num",+ "key('k','true')[4]/num",+ "key('k','true')[4]/num",+ "key('k','true')[last()=position()]",+ "key('k','true')[last()]",+ "key('k','true')[position()=1]/num",+ "key('k','true')[position()=4]/num",+ "key('key1','Mary Brady')|key('key2','Rick Rivello')",+ "key('marks',key('titles', 'Expressions')/finder)",+ "key('mykey', 'Expressions')",+ "key('mykey', 'Expressions')/p",+ "key('mykey', 'Introduction')/p",+ "key('mykey', 'Patterns')",+ "key('mykey', 'Second Title in Structure')/p",+ "key('mykey', 'Stylesheet Structure')",+ "key('mykey', 'Stylesheet Structure')/p",+ "key('mykey', 1 )/p",+ "key('mykey', 1+1 )/p",+ "key('mykey', 3.0 )/p",+ "key('mykey', 3.7 )/p",+ "key('mykey',' ')/@title",+ "key('mykey','')/p",+ "key('mykey','Exp Section')/@title",+ "key('mykey','Expressions')/p",+ "key('mykey','Expressions')/p",+ "key('mykey','Intro Section')/@title",+ "key('mykey','Introduction')/p",+ "key('mykey','Introduction')/p",+ "key('mykey','SS Section')/@title",+ "key('mykey','Sort Section')/@title",+ "key('mykey','Sorting')/p",+ "key('mykey','Sorting')/p",+ "key('mykey','Stylesheet Structure')/p",+ "key('mykey','Stylesheet Structure')/p",+ "key('mykey',*//title)",+ "key('mykey1','foo' )/p",+ "key('mykey2', 1 )/p",+ "key('one','3') | key('two','3')",+ "key('smallspace', 'Expressions')/p",+ "key('smallspace', 'Expressions')/p",+ "key('smallspace', 'Introduction')/p",+ "key('smallspace', 'Introduction')/p",+ "key('smallspace', 'Stylesheet Structure')/p",+ "key('smallspace', 'Stylesheet Structure')/p",+ "key('test','foey')",+ "key('titles', .)",+ "key('two','3') | document('select59.xml')/child[@wide='3'] | child[@deep='3']",+ "key('which','3')",+ "keyword[@tag='sector']",+ "keyword[@tag='ticker']",+ "keyword[@tag='ticker']",+ "keyword[@tag='ticker']",+ "keyword[@tag='ticker']",+ "lang('en')",+ "last()",+ "local-name()",+ "local-name(.)",+ "local-name(baz1:a)",+ "local-name(baz2:b)",+ "local-name(baz2:b/@baz1:attrib2)",+ "local-name(namespace::*[1])",+ "local-name(namespace::*[string()='http://www.w3.org/1999/XMLSchema-instance'])",+ "local-name(namespace::*[string()='test'])",+ "local-name(xalan:nodeset($rtf)/*)",+ "main/a/descendant-or-self::*/@*",+ "main/size[@for='d']",+ "mi | do | fa | re",+ "mi[@mi2='mi2'] | do | fa/so/@so | fa | mi/@* | re | fa/@fa | do/@do",+ "month",+ "month",+ "month",+ "n",+ "n-2 - -n-1",+ "n-2 - n-1",+ "n-2+-n-1",+ "n0 div n1 div n2 div n3 div n4 div n5",+ "n0 div n1 div n2 div n3 div n4",+ "n0 div n1 div n2 div n3",+ "n1 div n2",+ "n1 mod n2",+ "n1*n2",+ "n1*n2*n3*n4",+ "n1*n2*n3*n4*n5*n6*n7*n8*n9*n10",+ "n1+n2",+ "n1/@attrib + n2/@attrib",+ "n1/@attrib div n2/@attrib",+ "n1/@attrib mod n2/@attrib",+ "n2+3+$anum+7+n5",+ "n4",+ "n6*5-8*n2+5*2",+ "name",+ "name",+ "name",+ "name",+ "name",+ "name",+ "name",+ "name((ancestor::section|../ednote |following::title|../bogus)[1])",+ "name((ancestor::section|ancestor::simplesect |ancestor::article)[last()])",+ "name(/descendant-or-self::node()/child::near-north)",+ "name(/descendant-or-self::node()/descendant-or-self::north)",+ "name(/descendant-or-self::north)",+ "name(/descendant-or-self::north/child::near-north)",+ "name(/descendant-or-self::north/descendant-or-self::north)",+ "name(/descendant::near-north)",+ "name(/descendant::near-north/descendant-or-self::near-north)",+ "name(/descendant::node()/descendant-or-self::near-north)",+ "name(ancestor::*[1])",+ "name(ancestor::*[1])",+ "name(ancestor::*[2])",+ "name(ancestor::*[2])",+ "name(ancestor::*[3])",+ "name(ancestor::*[3])",+ "name(baz1:a)",+ "name(baz1:a/@baz2:attrib1)",+ "name(baz2:b)",+ "name(baz2:b/@baz1:attrib2)",+ "name(descendant-or-self::node()/child::near-north)",+ "name(descendant-or-self::node()/child::node()/child::far-west)",+ "name(descendant-or-self::node()/child::node()/descendant-or-self::near-north)",+ "name(descendant-or-self::node()/descendant-or-self::node()/child::near-north)",+ "name(descendant-or-self::node()/descendant-or-self::node()/descendant-or-self::north)",+ "name(descendant-or-self::node()/descendant-or-self::north)",+ "name(descendant-or-self::node()/descendant::near-north)",+ "name(descendant-or-self::node()/descendant::node()/child::far-west)",+ "name(descendant-or-self::node()/descendant::node()/descendant-or-self::near-north)",+ "name(descendant-or-self::north/child::near-north)",+ "name(descendant-or-self::north/child::near-north/child::far-west)",+ "name(descendant-or-self::north/child::near-north/descendant-or-self::near-north)",+ "name(descendant-or-self::north/descendant-or-self::north)",+ "name(descendant-or-self::north/descendant-or-self::north/child::near-north)",+ "name(descendant-or-self::north/descendant-or-self::north/descendant-or-self::north)",+ "name(descendant-or-self::north/descendant::near-north)",+ "name(descendant-or-self::north/descendant::near-north/child::far-west)",+ "name(descendant-or-self::north/descendant::near-north/descendant-or-self::near-north)",+ "name(descendant::near-north/descendant-or-self::near-north)",+ "name(descendant::near-north/descendant-or-self::near-north/child::far-west)",+ "name(descendant::near-north/descendant-or-self::near-north/descendant-or-self::near-north)",+ "name(descendant::near-north/descendant::far-west)",+ "name(descendant::near-north/descendant::far-west/descendant-or-self::far-west)",+ "name(descendant::node()/descendant-or-self::near-north)",+ "name(descendant::node()/descendant-or-self::node()/child::far-west)",+ "name(descendant::node()/descendant-or-self::node()/descendant-or-self::near-north)",+ "name(descendant::node()/descendant::far-west)",+ "name(descendant::node()/descendant::node()/descendant-or-self::far-west)",+ "name(namespace::*[1])",+ "name(self::node()/descendant-or-self::node()/child::near-north)",+ "name(self::node()/descendant-or-self::node()/descendant-or-self::north)",+ "name(self::node()/descendant-or-self::north)",+ "name(self::node()/descendant-or-self::north/child::near-north)",+ "name(self::node()/descendant-or-self::north/descendant-or-self::north)",+ "name(self::node()/descendant::near-north)",+ "name(self::node()/descendant::near-north/child::far-west)",+ "name(self::node()/descendant::near-north/descendant-or-self::far-west)",+ "name(self::node()/descendant::node()/child::far-west)",+ "name(self::node()/descendant::node()/descendant-or-self::far-west)",+ "name(xalan:nodeset($rtf)/*)",+ "namespace-uri(baz1:a-two/@attrib1)",+ "namespace-uri(baz1:a/@baz2:attrib1)",+ "namespace-uri(baz2:b)",+ "namespace-uri(baz2:b-three)",+ "namespace-uri(baz2:b-three/@baz1:attrib2)",+ "namespace-uri(baz2:b-three/c-four)",+ "namespace-uri(baz2:b/@baz1:attrib2)",+ "namespace-uri(namespace::*[string()='http://www.w3.org/1999/XMLSchema-instance'])",+ "namespace-uri(namespace::*[string()='test'])",+ "namespace-uri(x)",+ "namespace-uri(xalan:nodeset($rtf)/default:docelem)",+ "namespace-uri(xalan:nodeset($rtf)/default:docelem/default:elem1)",+ "namespace-uri(xalan:nodeset($rtf)/default:docelem/test:elem3)",+ "namespace::*",+ "namespace::node()",+ "nitro:element(.)",+ "node",+ "node()|@*",+ "normalize-space($texts[1])",+ "normalize-space($thisvalue)",+ "normalize-space(' ab cd ef ')",+ "normalize-space()",+ "normalize-space(a)",+ "north/* | north/dup1 | north/dup2",+ "north/dup2 | document('select71.xml')/south/preceding-sibling[4] | north/*",+ "north/dup2 | north/dup1 | north/*",+ "not($x!='foo')",+ "not('')",+ "not('0')",+ "not(false() = false())",+ "not(false())",+ "not(true() = false())",+ "not(true())",+ "note[1]",+ "note[1]",+ "number($ResultTreeFragTest)",+ "number($emptyResultTreeFragTest)",+ "number($pvar2)",+ "number('')",+ "number('3')",+ "number('abc')",+ "number('xxx') - 10",+ "number('xxx') div 3",+ "number('xxx') mod 3",+ "number('xxx')=0",+ "number('xxx')=number('xxx')",+ "number()",+ "number(2)",+ "number(false())=0",+ "number(foo)",+ "number(n1)",+ "number(string(1.0))=1",+ "number(true())=1",+ "number(xalan:nodeset($rtf)/default:docelem/default:elem3[2])",+ "para[@id='1' and lang('en')]",+ "parent::*",+ "parent::*[1]",+ "parent::foo",+ "parent::near-north",+ "position()",+ "position()=1",+ "preceding-sibling::*",+ "preceding-sibling::*/following-sibling::*",+ "preceding-sibling::*[2]",+ "preceding-sibling::*[2]",+ "preceding-sibling::*[2]/following-sibling::*",+ "preceding-sibling::*[2]/following-sibling::*[4]",+ "preceding-sibling::*[2]/following-sibling::*[4]/preceding-sibling::*[5]/following-sibling::*[4]/following-sibling::*[2]",+ "preceding-sibling::*|following-sibling::*",+ "preceding-sibling::child1|//child3",+ "preceding-sibling::child1|following-sibling::child3",+ "preceding-sibling::foo[1]/@att1",+ "preceding-sibling::west",+ "preceding::*",+ "preceding::*[2]/../descendant::*[10]/following-sibling::east",+ "preceding::*[2]/../following::*",+ "preceding::*[4]",+ "preceding::foo[1]/@att1",+ "preceding::out-yonder-west",+ "preceding::text()",+ "preceding::text()[$this]",+ "primary/name/first",+ "primary/name/first",+ "processing-instruction()",+ "pt:xif('test')",+ "pt:xif(string($val))",+ "round(-1.1)=-1",+ "round(-1.5)",+ "round(-1.9)=-2",+ "round(-2.5)=-2",+ "round(0.0)",+ "round(1.1)=1",+ "round(1.24)",+ "round(1.5)=2",+ "round(1.9)=2",+ "round(2.5)",+ "round(2.999999)",+ "round(count(.//LINE) div count(.//SPEECH))",+ "round(n0)",+ "round(n1)",+ "round(n2)",+ "round(number('xxx'))",+ "row",+ "self::*",+ "self::*",+ "self::*[1]",+ "self::*[@center-attr-2]",+ "self::*[near-south]",+ "self::center",+ "self::child1|self::child2",+ "self::comment()",+ "self::foo",+ "self::node()",+ "self::node()",+ "self::node()",+ "self::node()",+ "self::processing-instruction()",+ "self::text()",+ "sigs",+ "sss//i",+ "sss//i",+ "sss/sss",+ "sss/sss",+ "starts-with('','')",+ "starts-with('ENCYCLOPEDIA', 'EN')",+ "starts-with('ENCYCLOPEDIA', 'ENCY')",+ "starts-with('ENCYCLOPEDIA', 'en')",+ "starts-with('ab', 'abc')",+ "starts-with('abc', '')",+ "starts-with('abc', 'bc')",+ "starts-with('true()', 'tr')",+ "starts-with(doc, 'ENCY')",+ "starts-with(doc, 'test')",+ "starts-with(doc/@attr, 'slam')",+ "starts-with(doc/@attr, 'wich')",+ "str:new(string(doc))",+ "str:toUpperCase($str-obj)",+ "string($ResultTreeFragTest)",+ "string($ResultTreeFragTest)",+ "string($emptyResultTreeFragTest)",+ "string($which)",+ "string('!From m!')",+ "string('!From n!')",+ "string('!From o!')",+ "string('!From p!')",+ "string('')",+ "string('test')",+ "string()",+ "string()",+ "string(0)",+ "string(2)",+ "string(av//*)",+ "string(doc)",+ "string(foo)",+ "string-length ()",+ "string-length($str)",+ "string-length('This is a test')",+ "string-length()",+ "string-length()",+ "string-length(.)",+ "string-length(doc)",+ "string-length(doc/a)",+ "sub1/child1|/doc/sub2/child2",+ "sub1/child1|sub2/child2",+ "subj",+ "substring('1999/04/01', 1, 0)",+ "substring('1999/04/01', 1, 4)",+ "substring('ENCYCLOPEDIA', 8)",+ "substring('ENCYCLOPEDIA', 8, 3)",+ "substring('abcdefghi',2,4)",+ "substring('abcdefghijk',0 div 0, 5)",+ "substring('abcdefghijk',4, 6)",+ "substring(@key,2,1)",+ "substring(doc, 1, 4)",+ "substring(doc/@attr, 1, 3)",+ "substring(doc/@attr, 2.5, 3.6)",+ "substring(doc/@attr, 4)",+ "substring(foo, 12, 3)",+ "substring(foo, 2, 2)",+ "substring-after($words,' ')",+ "substring-after('1999/04/01', '/')",+ "substring-after('1999/04/01', '1')",+ "substring-after('ENCYCLOPEDIA', '/')",+ "substring-after('ENCYCLOPEDIA', 'C')",+ "substring-after('abcdefghijk','l')",+ "substring-after(doc, '/')",+ "substring-after(doc/@attr, 'D')",+ "substring-after(doc/@attr, 'd')",+ "substring-after(doc/@attr, 'z')",+ "substring-after(foo, '/')",+ "substring-before('1999/04/01', '/')",+ "substring-before('ENCYCLOPEDIA', '/')",+ "substring-before('ENCYCLOPEDIA', 'C')",+ "substring-before('ENCYCLOPEDIA', 'c')",+ "substring-before('a','z')",+ "substring-before(doc, '/')",+ "substring-before(doc/@attr, 'D')",+ "substring-before(doc/@attr, 'd')",+ "substring-before(doc/@attr, 'z')",+ "substring-before(foo, '/')",+ "sum($rtf)",+ "sum(e)",+ "sum(e)",+ "sum(n)",+ "sum(n/@attrib)",+ "sum(x)",+ "sum(xalan:nodeset($rtf)/default:docelem/default:elem3)",+ "system-property('xsl:vendor')",+ "true() and false()",+ "true() and true()",+ "true() or 1 div 0",+ "true() or false()",+ "true() or true()",+ "true()",+ "true()=2",+ "width * depth",+ "xalan:nodeset($rtf)/default:docelem",+ "xalan:nodeset($rtf)/default:docelem/*",+ "xalan:nodeset($rtf)/default:docelem/default:elem1",+ "xalan:nodeset($rtf)/default:docelem/default:elem1/default:elem1b",+ "xalan:nodeset($rtf)/default:docelem/default:elem2/*",+ "xalan:nodeset($rtf)/default:docelem/default:elem4",+ "xalan:nodeset($rtf)/default:docelem/test:elem3",+ "xalan:nodeset($sorted)/item",+ "deep-equal(/,foo)"+ ]+++-- die folgenden tests wurden vom W3C auskommentiert+-- ab hier ersetzen alle ersten -- durch <+-- <!-- arg value="concat("a","b","c","d","ef")"/ -->+-- <!-- arg value="concat("bc", string(23))"/>+-- <test value="concat("cd", "34")"/>+-- <test value="concat("cd", 34)"/>+-- <test value="concat("x","yz")"/ -->++-- <!-- arg value="document("")//bdd:test"/>+-- <test value="document("")//ped:test"/>+-- <test value="document("")/xsl:stylesheet/ped:test[@attrib="yeha"]"/>+-- <test value="document("../impincl-test/mdocstest.xml")//a"/>+-- <test value="document("../impincl-test/mdocstest.xml")//b"/ -->++-- <!-- arg value="substring("12345", -1 div 0, 1 div 0)"/>+-- <test value="substring("12345", -42, 1 div 0)"/>+-- <test value="substring("12345", 0 div 0, 3)"/>+-- <test value="substring("12345", 0, 3)"/>+-- <test value="substring("12345", 1, 0 div 0)"/>+-- <test value="substring("12345", 1.5, 2.6)"/ -->++-- <!-- arg value="translate("B'B","'","`")"/>+-- <test value="translate("BAR","Rab","TxX")"/>+-- <test value="translate("BAR","abc","ABC")"/>+-- <test value="translate("bar","RAB","xyz")"/>+-- <test value="translate("bar","abc","ABC")"/>+-- <test value="translate("ddaaadddd","abcd","ABCxy")"/>+-- <test value="translate("zzaaazzz","abcz","ABC")"/>+-- <test value="translate(.,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>+-- <test value="translate(a,"abc","ABC")"/>+-- <test value="translate(a/@attrib,"lo","IT")"/>+-- <test value="translate(b,"ABC","abc")"/>+-- <test value="translate(b/@attrib,"LO","it")"/>+-- <test value="translate(b/@attrib,"lo","it")"/>+-- <test value="translate(normalize-space($s), " ", "_")"/ -->
+ examples/hxpath/XPathShell.hs view
@@ -0,0 +1,178 @@+-- ------------------------------------------------------------++{- |+ Module : XPathShell+ Copyright : Copyright (C) 2008 Uwe Schmidt+ License : MIT++ Maintainer : Uwe Schmidt (uwe@fh-wedel.de)+ Stability : experimental+ Portability: portable++ XPath example program for testing xpath evaluation+ with both evaluation stategies, the full XPath functionality+ and the limited but faster one for simple XPath queries++-}++-- ------------------------------------------------------------+++module Main+where++import qualified Control.Monad as M++import Text.XML.HXT.Arrow+import Text.XML.HXT.XPath++import System.Console.Editline.Readline+import System.Environment++import Text.ParserCombinators.Parsec ( runParser )++type NsEnv' = AssocList String String++main :: IO()+main+ = do+ args <- getArgs+ (path, env, doc) <- evalArgs args+ if not (null path) && not (null doc)+ then evalXPath path env (head doc)+ else evalLoop env doc++evalArgs :: [String] -> IO (String, NsEnv', XmlTrees)+evalArgs [] = evalArgs ("" : "[]" : "" : [])+evalArgs [doc] = evalArgs ("" : "[]" : doc : [])+evalArgs [path, doc] = evalArgs (path : "[]" : doc : [])+evalArgs [path, env, ""] = return (path, buildEnv env, [])+evalArgs [path, env, doc] = do+ (d, ne) <- loadDoc doc+ return (path, addEntries ne . buildEnv $ env, d)+evalArgs al = evalArgs (take 3 al)++buildEnv :: String -> NsEnv'+buildEnv env = (addEntries . read $ env) $ defaultEnv++loadDoc :: String -> IO ([XmlTree], NsEnv')+loadDoc doc+ = do+ d <- runX ( readDocument [ (a_tagsoup, v_0)+ , (a_parse_by_mimetype, v_1)+ , (a_check_namespaces, v_1)+ , (a_remove_whitespace, v_1)+ , (a_validate, v_0)+ , (a_canonicalize, v_1)+ ] doc+ >>>+ (documentStatusOk `guards` this)+ )+ let env = runLA (unlistA >>> collectNamespaceDecl) d+ return (d, env)++showDoc :: XmlTree -> IO ()+showDoc doc+ = runX ( constA doc+ >>>+ writeDocument [ (a_indent, v_1)+ , (a_no_xml_pi, v_1)+ ] ""+ )+ >> return ()++showTree :: XmlTree -> IO ()+showTree doc+ = runX ( constA doc+ >>>+ writeDocument [ (a_show_tree, v_1)+ , (a_no_xml_pi, v_1)+ ] ""+ )+ >> return ()++evalXPath :: String -> NsEnv' -> XmlTree -> IO()+evalXPath path env doc+ = putStrLn . unlines $+ [ "start xpath evaluation: " ++ pathS+ , " parsed xpath: " ++ pathString+ , " parsed xpath as tree:"+ , pathTree+ , "xpath result:"+ ] ++ xr +++ [ "end xpath evaluation: " ++ pathS+ ]+ where+ pathS = show $ path+ pathEx = runParser parseXPath (toNsEnv env) "" $ path+ pathString = either show show $ pathEx+ pathTree = either show formatXPathTree $ pathEx+ xr = runLA ( getXPathTreesWithNsEnv env path >>> xshow this) doc++evalLoop :: NsEnv' -> XmlTrees -> IO ()+evalLoop env doc+ = do+ maybeLine <- readline "xpath> "+ case maybeLine of + Nothing -> return () -- EOF / control-d+ Just ":q" -> return ()+ Just line -> do+ let ws = words line+ if null ws+ then evalLoop env doc+ else do+ addHistory line+ evalCmd (words line)+ where+ evalCmd [] = evalLoop env doc+ evalCmd [":ns",uri] = evalCmd [":ns", "", uri]+ evalCmd [":ns", ns, uri]+ = evalLoop (addEntry ns uri env) doc+ evalCmd (":?":_) = do+ putStrLn . unlines $+ [ "XPath Tester"+ , "Commands:"+ , ":l <document>\tload a document"+ , ":ns <uri>\tset default namespace"+ , ":ns <px> <uri>\tset namespace"+ , ":q\t\tquit"+ , ":s\t\tshow current document"+ , ":t\t\tshow current document in tree format"+ , ":x\t\tshow current namespace environment"+ , ":?\t\tthis message"+ , "<xpath-expr>\tevaluate XPath expression"+ ]+ evalLoop env doc+ evalCmd [":x"] = do+ putStrLn . unlines . map show $ env+ evalLoop env doc+ evalCmd [":s"] = do+ M.when (not . null $ doc) (showDoc . head $ doc)+ evalLoop env doc+ evalCmd [":t"] = do+ M.when (not . null $ doc) (showTree . head $ doc)+ evalLoop env doc+ evalCmd [":l",n] = do+ (nd, nv) <- loadDoc n+ if null nd+ then do+ putStrLn ("error when loading " ++ show n)+ evalLoop env doc+ else evalLoop (addEntries nv env) nd+ evalCmd ws@((':':_):_)+ = do+ putStrLn ("unknown command (:? for help): " ++ (show . unwords $ ws))+ evalLoop env doc+ evalCmd ws = do+ let path = unwords ws+ if null doc+ then putStrLn "no document loaded"+ else evalXPath path env (head doc)+ evalLoop env doc++defaultEnv :: NsEnv'+defaultEnv = [ ("xml",xmlNamespace)+ , ("xmlns",xmlnsNamespace)+ ]++-- ----------------------------------------
+ examples/hxpath/example1.xml view
@@ -0,0 +1,27 @@+<?xml version="1.0"?>++<!DOCTYPE rezept [+<!ATTLIST rezept xml:lang CDATA #IMPLIED>+<!ELEMENT rezept (zutat*, anleitung*)>+<!ELEMENT zutat (#PCDATA)>+<!ATTLIST zutat id ID #IMPLIED>+<!ATTLIST zutat xml:lang CDATA #IMPLIED>+<!ATTLIST zutat xmlns:xlink CDATA #IMPLIED>+<!ATTLIST zutat xlink:type CDATA #IMPLIED>+<!ATTLIST zutat xlink:href CDATA #IMPLIED>+<!ELEMENT anleitung (#PCDATA)>+]>++<?xml-stylesheet href="style.xsl" type="text/xml"?>+<rezept>+ <zutat id="mehl">200g Mehl</zutat>+ <zutat id="mehl">z 2</zutat>+ <zutat id="mehl">z 3</zutat>+ <!-- weitere Zutaten -->+ <anleitung>+ Zuerst nehmen Sie das+ <zutat xmlns:xlink="http://www.w3.org/1999/xlink"+ xlink:type="simple" xlink:href="mehl">Mehl</zutat>+ und mischen es mit ...+ </anleitung>+</rezept>
+ examples/hxpath/xhtml/xhtml-lat1.ent view
@@ -0,0 +1,196 @@+<!-- Portions (C) International Organization for Standardization 1986+ Permission to copy in any form is granted for use with+ conforming SGML systems and applications as defined in+ ISO 8879, provided this notice is included in all copies.+-->+<!-- Character entity set. Typical invocation:+ <!ENTITY % HTMLlat1 PUBLIC+ "-//W3C//ENTITIES Latin 1 for XHTML//EN"+ "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent">+ %HTMLlat1;+-->++<!ENTITY nbsp " "> <!-- no-break space = non-breaking space,+ U+00A0 ISOnum -->+<!ENTITY iexcl "¡"> <!-- inverted exclamation mark, U+00A1 ISOnum -->+<!ENTITY cent "¢"> <!-- cent sign, U+00A2 ISOnum -->+<!ENTITY pound "£"> <!-- pound sign, U+00A3 ISOnum -->+<!ENTITY curren "¤"> <!-- currency sign, U+00A4 ISOnum -->+<!ENTITY yen "¥"> <!-- yen sign = yuan sign, U+00A5 ISOnum -->+<!ENTITY brvbar "¦"> <!-- broken bar = broken vertical bar,+ U+00A6 ISOnum -->+<!ENTITY sect "§"> <!-- section sign, U+00A7 ISOnum -->+<!ENTITY uml "¨"> <!-- diaeresis = spacing diaeresis,+ U+00A8 ISOdia -->+<!ENTITY copy "©"> <!-- copyright sign, U+00A9 ISOnum -->+<!ENTITY ordf "ª"> <!-- feminine ordinal indicator, U+00AA ISOnum -->+<!ENTITY laquo "«"> <!-- left-pointing double angle quotation mark+ = left pointing guillemet, U+00AB ISOnum -->+<!ENTITY not "¬"> <!-- not sign = discretionary hyphen,+ U+00AC ISOnum -->+<!ENTITY shy "­"> <!-- soft hyphen = discretionary hyphen,+ U+00AD ISOnum -->+<!ENTITY reg "®"> <!-- registered sign = registered trade mark sign,+ U+00AE ISOnum -->+<!ENTITY macr "¯"> <!-- macron = spacing macron = overline+ = APL overbar, U+00AF ISOdia -->+<!ENTITY deg "°"> <!-- degree sign, U+00B0 ISOnum -->+<!ENTITY plusmn "±"> <!-- plus-minus sign = plus-or-minus sign,+ U+00B1 ISOnum -->+<!ENTITY sup2 "²"> <!-- superscript two = superscript digit two+ = squared, U+00B2 ISOnum -->+<!ENTITY sup3 "³"> <!-- superscript three = superscript digit three+ = cubed, U+00B3 ISOnum -->+<!ENTITY acute "´"> <!-- acute accent = spacing acute,+ U+00B4 ISOdia -->+<!ENTITY micro "µ"> <!-- micro sign, U+00B5 ISOnum -->+<!ENTITY para "¶"> <!-- pilcrow sign = paragraph sign,+ U+00B6 ISOnum -->+<!ENTITY middot "·"> <!-- middle dot = Georgian comma+ = Greek middle dot, U+00B7 ISOnum -->+<!ENTITY cedil "¸"> <!-- cedilla = spacing cedilla, U+00B8 ISOdia -->+<!ENTITY sup1 "¹"> <!-- superscript one = superscript digit one,+ U+00B9 ISOnum -->+<!ENTITY ordm "º"> <!-- masculine ordinal indicator,+ U+00BA ISOnum -->+<!ENTITY raquo "»"> <!-- right-pointing double angle quotation mark+ = right pointing guillemet, U+00BB ISOnum -->+<!ENTITY frac14 "¼"> <!-- vulgar fraction one quarter+ = fraction one quarter, U+00BC ISOnum -->+<!ENTITY frac12 "½"> <!-- vulgar fraction one half+ = fraction one half, U+00BD ISOnum -->+<!ENTITY frac34 "¾"> <!-- vulgar fraction three quarters+ = fraction three quarters, U+00BE ISOnum -->+<!ENTITY iquest "¿"> <!-- inverted question mark+ = turned question mark, U+00BF ISOnum -->+<!ENTITY Agrave "À"> <!-- latin capital letter A with grave+ = latin capital letter A grave,+ U+00C0 ISOlat1 -->+<!ENTITY Aacute "Á"> <!-- latin capital letter A with acute,+ U+00C1 ISOlat1 -->+<!ENTITY Acirc "Â"> <!-- latin capital letter A with circumflex,+ U+00C2 ISOlat1 -->+<!ENTITY Atilde "Ã"> <!-- latin capital letter A with tilde,+ U+00C3 ISOlat1 -->+<!ENTITY Auml "Ä"> <!-- latin capital letter A with diaeresis,+ U+00C4 ISOlat1 -->+<!ENTITY Aring "Å"> <!-- latin capital letter A with ring above+ = latin capital letter A ring,+ U+00C5 ISOlat1 -->+<!ENTITY AElig "Æ"> <!-- latin capital letter AE+ = latin capital ligature AE,+ U+00C6 ISOlat1 -->+<!ENTITY Ccedil "Ç"> <!-- latin capital letter C with cedilla,+ U+00C7 ISOlat1 -->+<!ENTITY Egrave "È"> <!-- latin capital letter E with grave,+ U+00C8 ISOlat1 -->+<!ENTITY Eacute "É"> <!-- latin capital letter E with acute,+ U+00C9 ISOlat1 -->+<!ENTITY Ecirc "Ê"> <!-- latin capital letter E with circumflex,+ U+00CA ISOlat1 -->+<!ENTITY Euml "Ë"> <!-- latin capital letter E with diaeresis,+ U+00CB ISOlat1 -->+<!ENTITY Igrave "Ì"> <!-- latin capital letter I with grave,+ U+00CC ISOlat1 -->+<!ENTITY Iacute "Í"> <!-- latin capital letter I with acute,+ U+00CD ISOlat1 -->+<!ENTITY Icirc "Î"> <!-- latin capital letter I with circumflex,+ U+00CE ISOlat1 -->+<!ENTITY Iuml "Ï"> <!-- latin capital letter I with diaeresis,+ U+00CF ISOlat1 -->+<!ENTITY ETH "Ð"> <!-- latin capital letter ETH, U+00D0 ISOlat1 -->+<!ENTITY Ntilde "Ñ"> <!-- latin capital letter N with tilde,+ U+00D1 ISOlat1 -->+<!ENTITY Ograve "Ò"> <!-- latin capital letter O with grave,+ U+00D2 ISOlat1 -->+<!ENTITY Oacute "Ó"> <!-- latin capital letter O with acute,+ U+00D3 ISOlat1 -->+<!ENTITY Ocirc "Ô"> <!-- latin capital letter O with circumflex,+ U+00D4 ISOlat1 -->+<!ENTITY Otilde "Õ"> <!-- latin capital letter O with tilde,+ U+00D5 ISOlat1 -->+<!ENTITY Ouml "Ö"> <!-- latin capital letter O with diaeresis,+ U+00D6 ISOlat1 -->+<!ENTITY times "×"> <!-- multiplication sign, U+00D7 ISOnum -->+<!ENTITY Oslash "Ø"> <!-- latin capital letter O with stroke+ = latin capital letter O slash,+ U+00D8 ISOlat1 -->+<!ENTITY Ugrave "Ù"> <!-- latin capital letter U with grave,+ U+00D9 ISOlat1 -->+<!ENTITY Uacute "Ú"> <!-- latin capital letter U with acute,+ U+00DA ISOlat1 -->+<!ENTITY Ucirc "Û"> <!-- latin capital letter U with circumflex,+ U+00DB ISOlat1 -->+<!ENTITY Uuml "Ü"> <!-- latin capital letter U with diaeresis,+ U+00DC ISOlat1 -->+<!ENTITY Yacute "Ý"> <!-- latin capital letter Y with acute,+ U+00DD ISOlat1 -->+<!ENTITY THORN "Þ"> <!-- latin capital letter THORN,+ U+00DE ISOlat1 -->+<!ENTITY szlig "ß"> <!-- latin small letter sharp s = ess-zed,+ U+00DF ISOlat1 -->+<!ENTITY agrave "à"> <!-- latin small letter a with grave+ = latin small letter a grave,+ U+00E0 ISOlat1 -->+<!ENTITY aacute "á"> <!-- latin small letter a with acute,+ U+00E1 ISOlat1 -->+<!ENTITY acirc "â"> <!-- latin small letter a with circumflex,+ U+00E2 ISOlat1 -->+<!ENTITY atilde "ã"> <!-- latin small letter a with tilde,+ U+00E3 ISOlat1 -->+<!ENTITY auml "ä"> <!-- latin small letter a with diaeresis,+ U+00E4 ISOlat1 -->+<!ENTITY aring "å"> <!-- latin small letter a with ring above+ = latin small letter a ring,+ U+00E5 ISOlat1 -->+<!ENTITY aelig "æ"> <!-- latin small letter ae+ = latin small ligature ae, U+00E6 ISOlat1 -->+<!ENTITY ccedil "ç"> <!-- latin small letter c with cedilla,+ U+00E7 ISOlat1 -->+<!ENTITY egrave "è"> <!-- latin small letter e with grave,+ U+00E8 ISOlat1 -->+<!ENTITY eacute "é"> <!-- latin small letter e with acute,+ U+00E9 ISOlat1 -->+<!ENTITY ecirc "ê"> <!-- latin small letter e with circumflex,+ U+00EA ISOlat1 -->+<!ENTITY euml "ë"> <!-- latin small letter e with diaeresis,+ U+00EB ISOlat1 -->+<!ENTITY igrave "ì"> <!-- latin small letter i with grave,+ U+00EC ISOlat1 -->+<!ENTITY iacute "í"> <!-- latin small letter i with acute,+ U+00ED ISOlat1 -->+<!ENTITY icirc "î"> <!-- latin small letter i with circumflex,+ U+00EE ISOlat1 -->+<!ENTITY iuml "ï"> <!-- latin small letter i with diaeresis,+ U+00EF ISOlat1 -->+<!ENTITY eth "ð"> <!-- latin small letter eth, U+00F0 ISOlat1 -->+<!ENTITY ntilde "ñ"> <!-- latin small letter n with tilde,+ U+00F1 ISOlat1 -->+<!ENTITY ograve "ò"> <!-- latin small letter o with grave,+ U+00F2 ISOlat1 -->+<!ENTITY oacute "ó"> <!-- latin small letter o with acute,+ U+00F3 ISOlat1 -->+<!ENTITY ocirc "ô"> <!-- latin small letter o with circumflex,+ U+00F4 ISOlat1 -->+<!ENTITY otilde "õ"> <!-- latin small letter o with tilde,+ U+00F5 ISOlat1 -->+<!ENTITY ouml "ö"> <!-- latin small letter o with diaeresis,+ U+00F6 ISOlat1 -->+<!ENTITY divide "÷"> <!-- division sign, U+00F7 ISOnum -->+<!ENTITY oslash "ø"> <!-- latin small letter o with stroke,+ = latin small letter o slash,+ U+00F8 ISOlat1 -->+<!ENTITY ugrave "ù"> <!-- latin small letter u with grave,+ U+00F9 ISOlat1 -->+<!ENTITY uacute "ú"> <!-- latin small letter u with acute,+ U+00FA ISOlat1 -->+<!ENTITY ucirc "û"> <!-- latin small letter u with circumflex,+ U+00FB ISOlat1 -->+<!ENTITY uuml "ü"> <!-- latin small letter u with diaeresis,+ U+00FC ISOlat1 -->+<!ENTITY yacute "ý"> <!-- latin small letter y with acute,+ U+00FD ISOlat1 -->+<!ENTITY thorn "þ"> <!-- latin small letter thorn with,+ U+00FE ISOlat1 -->+<!ENTITY yuml "ÿ"> <!-- latin small letter y with diaeresis,+ U+00FF ISOlat1 -->
+ examples/hxpath/xhtml/xhtml-special.ent view
@@ -0,0 +1,79 @@+<!-- Special characters for HTML -->++<!-- Character entity set. Typical invocation:+ <!ENTITY % HTMLspecial PUBLIC+ "-//W3C//ENTITIES Special for XHTML//EN"+ "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent">+ %HTMLspecial;+-->++<!-- Portions (C) International Organization for Standardization 1986:+ Permission to copy in any form is granted for use with+ conforming SGML systems and applications as defined in+ ISO 8879, provided this notice is included in all copies.+-->++<!-- Relevant ISO entity set is given unless names are newly introduced.+ New names (i.e., not in ISO 8879 list) do not clash with any+ existing ISO 8879 entity names. ISO 10646 character numbers+ are given for each character, in hex. values are decimal+ conversions of the ISO 10646 values and refer to the document+ character set. Names are Unicode names. +-->++<!-- C0 Controls and Basic Latin -->+<!ENTITY quot """> <!-- quotation mark = APL quote,+ U+0022 ISOnum -->+<!ENTITY amp "&#38;"> <!-- ampersand, U+0026 ISOnum -->+<!ENTITY lt "&#60;"> <!-- less-than sign, U+003C ISOnum -->+<!ENTITY gt ">"> <!-- greater-than sign, U+003E ISOnum -->+<!ENTITY apos "'"> <!-- apostrophe mark, U+0027 ISOnum -->++<!-- Latin Extended-A -->+<!ENTITY OElig "Œ"> <!-- latin capital ligature OE,+ U+0152 ISOlat2 -->+<!ENTITY oelig "œ"> <!-- latin small ligature oe, U+0153 ISOlat2 -->+<!-- ligature is a misnomer, this is a separate character in some languages -->+<!ENTITY Scaron "Š"> <!-- latin capital letter S with caron,+ U+0160 ISOlat2 -->+<!ENTITY scaron "š"> <!-- latin small letter s with caron,+ U+0161 ISOlat2 -->+<!ENTITY Yuml "Ÿ"> <!-- latin capital letter Y with diaeresis,+ U+0178 ISOlat2 -->++<!-- Spacing Modifier Letters -->+<!ENTITY circ "ˆ"> <!-- modifier letter circumflex accent,+ U+02C6 ISOpub -->+<!ENTITY tilde "˜"> <!-- small tilde, U+02DC ISOdia -->++<!-- General Punctuation -->+<!ENTITY ensp " "> <!-- en space, U+2002 ISOpub -->+<!ENTITY emsp " "> <!-- em space, U+2003 ISOpub -->+<!ENTITY thinsp " "> <!-- thin space, U+2009 ISOpub -->+<!ENTITY zwnj "‌"> <!-- zero width non-joiner,+ U+200C NEW RFC 2070 -->+<!ENTITY zwj "‍"> <!-- zero width joiner, U+200D NEW RFC 2070 -->+<!ENTITY lrm "‎"> <!-- left-to-right mark, U+200E NEW RFC 2070 -->+<!ENTITY rlm "‏"> <!-- right-to-left mark, U+200F NEW RFC 2070 -->+<!ENTITY ndash "–"> <!-- en dash, U+2013 ISOpub -->+<!ENTITY mdash "—"> <!-- em dash, U+2014 ISOpub -->+<!ENTITY lsquo "‘"> <!-- left single quotation mark,+ U+2018 ISOnum -->+<!ENTITY rsquo "’"> <!-- right single quotation mark,+ U+2019 ISOnum -->+<!ENTITY sbquo "‚"> <!-- single low-9 quotation mark, U+201A NEW -->+<!ENTITY ldquo "“"> <!-- left double quotation mark,+ U+201C ISOnum -->+<!ENTITY rdquo "”"> <!-- right double quotation mark,+ U+201D ISOnum -->+<!ENTITY bdquo "„"> <!-- double low-9 quotation mark, U+201E NEW -->+<!ENTITY dagger "†"> <!-- dagger, U+2020 ISOpub -->+<!ENTITY Dagger "‡"> <!-- double dagger, U+2021 ISOpub -->+<!ENTITY permil "‰"> <!-- per mille sign, U+2030 ISOtech -->+<!ENTITY lsaquo "‹"> <!-- single left-pointing angle quotation mark,+ U+2039 ISO proposed -->+<!-- lsaquo is proposed but not yet ISO standardized -->+<!ENTITY rsaquo "›"> <!-- single right-pointing angle quotation mark,+ U+203A ISO proposed -->+<!-- rsaquo is proposed but not yet ISO standardized -->+<!ENTITY euro "€"> <!-- euro sign, U+20AC NEW -->
+ examples/hxpath/xhtml/xhtml-symbol.ent view
@@ -0,0 +1,242 @@+<!-- Mathematical, Greek and Symbolic characters for HTML -->++<!-- Character entity set. Typical invocation:+ <!ENTITY % HTMLsymbol PUBLIC+ "-//W3C//ENTITIES Symbols for XHTML//EN"+ "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent">+ %HTMLsymbol;+-->++<!-- Portions (C) International Organization for Standardization 1986:+ Permission to copy in any form is granted for use with+ conforming SGML systems and applications as defined in+ ISO 8879, provided this notice is included in all copies.+-->++<!-- Relevant ISO entity set is given unless names are newly introduced.+ New names (i.e., not in ISO 8879 list) do not clash with any+ existing ISO 8879 entity names. ISO 10646 character numbers+ are given for each character, in hex. values are decimal+ conversions of the ISO 10646 values and refer to the document+ character set. Names are Unicode names. +-->++<!-- Latin Extended-B -->+<!ENTITY fnof "ƒ"> <!-- latin small f with hook = function+ = florin, U+0192 ISOtech -->++<!-- Greek -->+<!ENTITY Alpha "Α"> <!-- greek capital letter alpha, U+0391 -->+<!ENTITY Beta "Β"> <!-- greek capital letter beta, U+0392 -->+<!ENTITY Gamma "Γ"> <!-- greek capital letter gamma,+ U+0393 ISOgrk3 -->+<!ENTITY Delta "Δ"> <!-- greek capital letter delta,+ U+0394 ISOgrk3 -->+<!ENTITY Epsilon "Ε"> <!-- greek capital letter epsilon, U+0395 -->+<!ENTITY Zeta "Ζ"> <!-- greek capital letter zeta, U+0396 -->+<!ENTITY Eta "Η"> <!-- greek capital letter eta, U+0397 -->+<!ENTITY Theta "Θ"> <!-- greek capital letter theta,+ U+0398 ISOgrk3 -->+<!ENTITY Iota "Ι"> <!-- greek capital letter iota, U+0399 -->+<!ENTITY Kappa "Κ"> <!-- greek capital letter kappa, U+039A -->+<!ENTITY Lambda "Λ"> <!-- greek capital letter lambda,+ U+039B ISOgrk3 -->+<!ENTITY Mu "Μ"> <!-- greek capital letter mu, U+039C -->+<!ENTITY Nu "Ν"> <!-- greek capital letter nu, U+039D -->+<!ENTITY Xi "Ξ"> <!-- greek capital letter xi, U+039E ISOgrk3 -->+<!ENTITY Omicron "Ο"> <!-- greek capital letter omicron, U+039F -->+<!ENTITY Pi "Π"> <!-- greek capital letter pi, U+03A0 ISOgrk3 -->+<!ENTITY Rho "Ρ"> <!-- greek capital letter rho, U+03A1 -->+<!-- there is no Sigmaf, and no U+03A2 character either -->+<!ENTITY Sigma "Σ"> <!-- greek capital letter sigma,+ U+03A3 ISOgrk3 -->+<!ENTITY Tau "Τ"> <!-- greek capital letter tau, U+03A4 -->+<!ENTITY Upsilon "Υ"> <!-- greek capital letter upsilon,+ U+03A5 ISOgrk3 -->+<!ENTITY Phi "Φ"> <!-- greek capital letter phi,+ U+03A6 ISOgrk3 -->+<!ENTITY Chi "Χ"> <!-- greek capital letter chi, U+03A7 -->+<!ENTITY Psi "Ψ"> <!-- greek capital letter psi,+ U+03A8 ISOgrk3 -->+<!ENTITY Omega "Ω"> <!-- greek capital letter omega,+ U+03A9 ISOgrk3 -->++<!ENTITY alpha "α"> <!-- greek small letter alpha,+ U+03B1 ISOgrk3 -->+<!ENTITY beta "β"> <!-- greek small letter beta, U+03B2 ISOgrk3 -->+<!ENTITY gamma "γ"> <!-- greek small letter gamma,+ U+03B3 ISOgrk3 -->+<!ENTITY delta "δ"> <!-- greek small letter delta,+ U+03B4 ISOgrk3 -->+<!ENTITY epsilon "ε"> <!-- greek small letter epsilon,+ U+03B5 ISOgrk3 -->+<!ENTITY zeta "ζ"> <!-- greek small letter zeta, U+03B6 ISOgrk3 -->+<!ENTITY eta "η"> <!-- greek small letter eta, U+03B7 ISOgrk3 -->+<!ENTITY theta "θ"> <!-- greek small letter theta,+ U+03B8 ISOgrk3 -->+<!ENTITY iota "ι"> <!-- greek small letter iota, U+03B9 ISOgrk3 -->+<!ENTITY kappa "κ"> <!-- greek small letter kappa,+ U+03BA ISOgrk3 -->+<!ENTITY lambda "λ"> <!-- greek small letter lambda,+ U+03BB ISOgrk3 -->+<!ENTITY mu "μ"> <!-- greek small letter mu, U+03BC ISOgrk3 -->+<!ENTITY nu "ν"> <!-- greek small letter nu, U+03BD ISOgrk3 -->+<!ENTITY xi "ξ"> <!-- greek small letter xi, U+03BE ISOgrk3 -->+<!ENTITY omicron "ο"> <!-- greek small letter omicron, U+03BF NEW -->+<!ENTITY pi "π"> <!-- greek small letter pi, U+03C0 ISOgrk3 -->+<!ENTITY rho "ρ"> <!-- greek small letter rho, U+03C1 ISOgrk3 -->+<!ENTITY sigmaf "ς"> <!-- greek small letter final sigma,+ U+03C2 ISOgrk3 -->+<!ENTITY sigma "σ"> <!-- greek small letter sigma,+ U+03C3 ISOgrk3 -->+<!ENTITY tau "τ"> <!-- greek small letter tau, U+03C4 ISOgrk3 -->+<!ENTITY upsilon "υ"> <!-- greek small letter upsilon,+ U+03C5 ISOgrk3 -->+<!ENTITY phi "φ"> <!-- greek small letter phi, U+03C6 ISOgrk3 -->+<!ENTITY chi "χ"> <!-- greek small letter chi, U+03C7 ISOgrk3 -->+<!ENTITY psi "ψ"> <!-- greek small letter psi, U+03C8 ISOgrk3 -->+<!ENTITY omega "ω"> <!-- greek small letter omega,+ U+03C9 ISOgrk3 -->+<!ENTITY thetasym "ϑ"> <!-- greek small letter theta symbol,+ U+03D1 NEW -->+<!ENTITY upsih "ϒ"> <!-- greek upsilon with hook symbol,+ U+03D2 NEW -->+<!ENTITY piv "ϖ"> <!-- greek pi symbol, U+03D6 ISOgrk3 -->++<!-- General Punctuation -->+<!ENTITY bull "•"> <!-- bullet = black small circle,+ U+2022 ISOpub -->+<!-- bullet is NOT the same as bullet operator, U+2219 -->+<!ENTITY hellip "…"> <!-- horizontal ellipsis = three dot leader,+ U+2026 ISOpub -->+<!ENTITY prime "′"> <!-- prime = minutes = feet, U+2032 ISOtech -->+<!ENTITY Prime "″"> <!-- double prime = seconds = inches,+ U+2033 ISOtech -->+<!ENTITY oline "‾"> <!-- overline = spacing overscore,+ U+203E NEW -->+<!ENTITY frasl "⁄"> <!-- fraction slash, U+2044 NEW -->++<!-- Letterlike Symbols -->+<!ENTITY weierp "℘"> <!-- script capital P = power set+ = Weierstrass p, U+2118 ISOamso -->+<!ENTITY image "ℑ"> <!-- blackletter capital I = imaginary part,+ U+2111 ISOamso -->+<!ENTITY real "ℜ"> <!-- blackletter capital R = real part symbol,+ U+211C ISOamso -->+<!ENTITY trade "™"> <!-- trade mark sign, U+2122 ISOnum -->+<!ENTITY alefsym "ℵ"> <!-- alef symbol = first transfinite cardinal,+ U+2135 NEW -->+<!-- alef symbol is NOT the same as hebrew letter alef,+ U+05D0 although the same glyph could be used to depict both characters -->++<!-- Arrows -->+<!ENTITY larr "←"> <!-- leftwards arrow, U+2190 ISOnum -->+<!ENTITY uarr "↑"> <!-- upwards arrow, U+2191 ISOnum-->+<!ENTITY rarr "→"> <!-- rightwards arrow, U+2192 ISOnum -->+<!ENTITY darr "↓"> <!-- downwards arrow, U+2193 ISOnum -->+<!ENTITY harr "↔"> <!-- left right arrow, U+2194 ISOamsa -->+<!ENTITY crarr "↵"> <!-- downwards arrow with corner leftwards+ = carriage return, U+21B5 NEW -->+<!ENTITY lArr "⇐"> <!-- leftwards double arrow, U+21D0 ISOtech -->+<!-- Unicode does not say that lArr is the same as the 'is implied by' arrow+ but also does not have any other character for that function. So ? lArr can+ be used for 'is implied by' as ISOtech suggests -->+<!ENTITY uArr "⇑"> <!-- upwards double arrow, U+21D1 ISOamsa -->+<!ENTITY rArr "⇒"> <!-- rightwards double arrow,+ U+21D2 ISOtech -->+<!-- Unicode does not say this is the 'implies' character but does not have + another character with this function so ?+ rArr can be used for 'implies' as ISOtech suggests -->+<!ENTITY dArr "⇓"> <!-- downwards double arrow, U+21D3 ISOamsa -->+<!ENTITY hArr "⇔"> <!-- left right double arrow,+ U+21D4 ISOamsa -->++<!-- Mathematical Operators -->+<!ENTITY forall "∀"> <!-- for all, U+2200 ISOtech -->+<!ENTITY part "∂"> <!-- partial differential, U+2202 ISOtech -->+<!ENTITY exist "∃"> <!-- there exists, U+2203 ISOtech -->+<!ENTITY empty "∅"> <!-- empty set = null set = diameter,+ U+2205 ISOamso -->+<!ENTITY nabla "∇"> <!-- nabla = backward difference,+ U+2207 ISOtech -->+<!ENTITY isin "∈"> <!-- element of, U+2208 ISOtech -->+<!ENTITY notin "∉"> <!-- not an element of, U+2209 ISOtech -->+<!ENTITY ni "∋"> <!-- contains as member, U+220B ISOtech -->+<!-- should there be a more memorable name than 'ni'? -->+<!ENTITY prod "∏"> <!-- n-ary product = product sign,+ U+220F ISOamsb -->+<!-- prod is NOT the same character as U+03A0 'greek capital letter pi' though+ the same glyph might be used for both -->+<!ENTITY sum "∑"> <!-- n-ary sumation, U+2211 ISOamsb -->+<!-- sum is NOT the same character as U+03A3 'greek capital letter sigma'+ though the same glyph might be used for both -->+<!ENTITY minus "−"> <!-- minus sign, U+2212 ISOtech -->+<!ENTITY lowast "∗"> <!-- asterisk operator, U+2217 ISOtech -->+<!ENTITY radic "√"> <!-- square root = radical sign,+ U+221A ISOtech -->+<!ENTITY prop "∝"> <!-- proportional to, U+221D ISOtech -->+<!ENTITY infin "∞"> <!-- infinity, U+221E ISOtech -->+<!ENTITY ang "∠"> <!-- angle, U+2220 ISOamso -->+<!ENTITY and "∧"> <!-- logical and = wedge, U+2227 ISOtech -->+<!ENTITY or "∨"> <!-- logical or = vee, U+2228 ISOtech -->+<!ENTITY cap "∩"> <!-- intersection = cap, U+2229 ISOtech -->+<!ENTITY cup "∪"> <!-- union = cup, U+222A ISOtech -->+<!ENTITY int "∫"> <!-- integral, U+222B ISOtech -->+<!ENTITY there4 "∴"> <!-- therefore, U+2234 ISOtech -->+<!ENTITY sim "∼"> <!-- tilde operator = varies with = similar to,+ U+223C ISOtech -->+<!-- tilde operator is NOT the same character as the tilde, U+007E,+ although the same glyph might be used to represent both -->+<!ENTITY cong "≅"> <!-- approximately equal to, U+2245 ISOtech -->+<!ENTITY asymp "≈"> <!-- almost equal to = asymptotic to,+ U+2248 ISOamsr -->+<!ENTITY ne "≠"> <!-- not equal to, U+2260 ISOtech -->+<!ENTITY equiv "≡"> <!-- identical to, U+2261 ISOtech -->+<!ENTITY le "≤"> <!-- less-than or equal to, U+2264 ISOtech -->+<!ENTITY ge "≥"> <!-- greater-than or equal to,+ U+2265 ISOtech -->+<!ENTITY sub "⊂"> <!-- subset of, U+2282 ISOtech -->+<!ENTITY sup "⊃"> <!-- superset of, U+2283 ISOtech -->+<!-- note that nsup, 'not a superset of, U+2283' is not covered by the Symbol + font encoding and is not included. Should it be, for symmetry?+ It is in ISOamsn --> +<!ENTITY nsub "⊄"> <!-- not a subset of, U+2284 ISOamsn -->+<!ENTITY sube "⊆"> <!-- subset of or equal to, U+2286 ISOtech -->+<!ENTITY supe "⊇"> <!-- superset of or equal to,+ U+2287 ISOtech -->+<!ENTITY oplus "⊕"> <!-- circled plus = direct sum,+ U+2295 ISOamsb -->+<!ENTITY otimes "⊗"> <!-- circled times = vector product,+ U+2297 ISOamsb -->+<!ENTITY perp "⊥"> <!-- up tack = orthogonal to = perpendicular,+ U+22A5 ISOtech -->+<!ENTITY sdot "⋅"> <!-- dot operator, U+22C5 ISOamsb -->+<!-- dot operator is NOT the same character as U+00B7 middle dot -->++<!-- Miscellaneous Technical -->+<!ENTITY lceil "⌈"> <!-- left ceiling = apl upstile,+ U+2308 ISOamsc -->+<!ENTITY rceil "⌉"> <!-- right ceiling, U+2309 ISOamsc -->+<!ENTITY lfloor "⌊"> <!-- left floor = apl downstile,+ U+230A ISOamsc -->+<!ENTITY rfloor "⌋"> <!-- right floor, U+230B ISOamsc -->+<!ENTITY lang "〈"> <!-- left-pointing angle bracket = bra,+ U+2329 ISOtech -->+<!-- lang is NOT the same character as U+003C 'less than' + or U+2039 'single left-pointing angle quotation mark' -->+<!ENTITY rang "〉"> <!-- right-pointing angle bracket = ket,+ U+232A ISOtech -->+<!-- rang is NOT the same character as U+003E 'greater than' + or U+203A 'single right-pointing angle quotation mark' -->++<!-- Geometric Shapes -->+<!ENTITY loz "◊"> <!-- lozenge, U+25CA ISOpub -->++<!-- Miscellaneous Symbols -->+<!ENTITY spades "♠"> <!-- black spade suit, U+2660 ISOpub -->+<!-- black here seems to mean filled as opposed to hollow -->+<!ENTITY clubs "♣"> <!-- black club suit = shamrock,+ U+2663 ISOpub -->+<!ENTITY hearts "♥"> <!-- black heart suit = valentine,+ U+2665 ISOpub -->+<!ENTITY diams "♦"> <!-- black diamond suit, U+2666 ISOpub -->
+ examples/hxpath/xhtml/xhtml.xml view
@@ -0,0 +1,1484 @@+<!DOCTYPE html SYSTEM "xhtml1-strict.dtd">+<?xml-stylesheet href="http://www.w3.org/StyleSheets/TR/W3C-REC.css" type="text/css"?>+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">+<head>+<title>XHTML 1.0: The Extensible HyperText Markup+Language</title>+<link rel="stylesheet"+href="http://www.w3.org/StyleSheets/TR/W3C-REC.css" type="text/css" />+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />+<style type="text/css">+span.term { font-style: italic; color: rgb(0, 0, 192) }+code {+ color: green;+ font-family: monospace;+ font-weight: bold;+}++code.greenmono {+ color: green;+ font-family: monospace;+ font-weight: bold;+}+.good {+ border: solid green;+ border-width: 2px;+ color: green;+ font-weight: bold;+ margin-right: 5%;+ margin-left: 0;+}+.bad {+ border: solid red;+ border-width: 2px;+ margin-left: 0;+ margin-right: 5%;+ color: rgb(192, 101, 101);+}++img {+ color: white;+ border: none;+}++div.navbar { text-align: center; }+div.contents {+ background-color: rgb(204,204,255);+ padding: 0.5em;+ border: none;+ margin-right: 5%;+}+.tocline { list-style: none; }+table.exceptions { background-color: rgb(255,255,153); }+</style>+</head>+<body>+<div class="navbar">+ <a href="#toc">table of contents</a>+ <hr />+</div>+<div class="head"><p><a href="http://www.w3.org/"><img class="head"+src="http://www.w3.org/Icons/WWW/w3c_home.gif" alt="W3C" /></a></p>++<h1 class="head"><a name="title" id="title">XHTML</a><sup>™</sup> 1.0:+The Extensible HyperText Markup Language</h1>++<h2>A Reformulation of HTML 4 in XML 1.0</h2>++<h3>W3C Recommendation 26 January 2000</h3>++<dl>+<dt>This version:</dt>++<dd><a href=+"http://www.w3.org/TR/2000/REC-xhtml1-20000126">+http://www.w3.org/TR/2000/REC-xhtml1-20000126</a> <br />+(<a href="xhtml1.ps">Postscript version</a>,+<a href="xhtml1.pdf">PDF version</a>,+<a href="xhtml1.zip">ZIP archive</a>, or+<a href="xhtml1.tgz">Gzip'd TAR archive</a>)+</dd>++<dt>Latest version:</dt>++<dd><a href="http://www.w3.org/TR/xhtml1">+http://www.w3.org/TR/xhtml1</a></dd>++<dt>Previous version:</dt>++<dd><a href=+"http://www.w3.org/TR/1999/PR-xhtml1-19991210">+http://www.w3.org/TR/1999/PR-xhtml1-19991210</a></dd>++<dt>Authors:</dt>++<dd>See <a href="#acks">acknowledgements</a>.</dd>+</dl>++<p class="copyright"><a+href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright"> Copyright</a>+©2000 <a href="http://www.w3.org/"><abbr title="World Wide Web+Consortium">W3C</abbr></a><sup>®</sup> (<a+href="http://www.lcs.mit.edu/"><abbr+title="Massachusetts Institute of Technology">MIT</abbr></a>, <a+href="http://www.inria.fr/"><abbr+lang="fr" title="Institut National de Recherche en Informatique et+Automatique">INRIA</abbr></a>, <a+href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved. W3C <a+href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,+<a+href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a>,+<a+href="http://www.w3.org/Consortium/Legal/copyright-documents-19990405">document+use</a> and <a+href="http://www.w3.org/Consortium/Legal/copyright-software-19980720">software+licensing</a> rules+apply.</p>+<hr />+</div>++<h2 class="notoc">Abstract</h2>++<p>This specification defines <abbr title="Extensible Hypertext Markup+Language">XHTML</abbr> 1.0, a reformulation of HTML 4+as an XML 1.0 application, and three <abbr title="Document Type+Definition">DTDs</abbr> corresponding to+the ones defined by HTML 4. The semantics of the elements and+their attributes are defined in the W3C Recommendation for HTML 4.+These semantics provide the foundation for future+extensibility of XHTML. Compatibility with existing HTML user+agents is possible by following a small set of guidelines.</p>++<h2>Status of this document</h2>++<p><em>This section describes the status of this document at the time+of its publication. Other documents may supersede this document. The+latest status of this document series is maintained at the W3C.</em></p>++<p>+This document has been reviewed by W3C Members and other+interested parties and has been endorsed by the Director+as a W3C Recommendation. It is a stable document and may be+used as reference material or cited as a normative+reference from another document. W3C's role in making the+Recommendation is to draw attention to the specification and+to promote its widespread deployment. This enhances the+functionality and interoperability of the Web.+</p>+<p>This document has been produced as part of the <a href=+"http://www.w3.org/MarkUp/">W3C HTML Activity</a>. The goals of+the <a href="http://www.w3.org/MarkUp/Group/">HTML Working+Group</a> <i>(<a href="http://cgi.w3.org/MemberAccess/">members+only</a>)</i> are discussed in the <a href=+"http://www.w3.org/MarkUp/Group/HTMLcharter">HTML Working Group+charter</a> <i>(<a href="http://cgi.w3.org/MemberAccess/">members+only</a>)</i>.</p>++<p>A list of current W3C Recommendations and other technical documents+can be found at <a+href="http://www.w3.org/TR">http://www.w3.org/TR</a>.</p>++<p>Public discussion on <abbr title="HyperText Markup+Language">HTML</abbr> features takes place on the mailing list <a+href="mailto:www-html@w3.org"> www-html@w3.org</a> (<a href=+"http://lists.w3.org/Archives/Public/www-html/">archive</a>).</p>++<p>Please report errors in this document to <a+href="mailto:www-html-editor@w3.org">www-html-editor@w3.org</a>.</p>++<p>The list of known errors in this specification is available at <a+href="http://www.w3.org/2000/01/REC-xhtml1-20000126-errata">http://www.w3.org/2000/01/REC-xhtml1-20000126-errata</a>.</p>++<h2 class="notoc"><a id="toc" name="toc">Contents</a></h2>++<div class="contents">+<ul class="toc">+<li class="tocline">1. <a href="#xhtml">What is XHTML?</a>++<ul class="toc">+<li class="tocline">1.1 <a href="#html4">What is HTML 4?</a></li>++<li class="tocline">1.2 <a href="#xml">What is XML?</a></li>++<li class="tocline">1.3 <a href="#why">Why the need for XHTML?</a></li>+</ul>+</li>++<li class="tocline">2. <a href="#defs">Definitions</a>++<ul class="toc">+<li class="tocline">2.1 <a href="#terms">Terminology</a></li>++<li class="tocline">2.2 <a href="#general">General Terms</a></li>+</ul>+</li>++<li class="tocline">3. <a href="#normative">Normative Definition of XHTML 1.0</a>+++<ul class="toc">+<li class="tocline">3.1 <a href="#docconf">Document Conformance</a></li>++<li class="tocline">3.2 <a href="#uaconf">User Agent Conformance</a></li>+</ul>+</li>++<li class="tocline">4. <a href="#diffs">Differences with HTML 4</a>++</li>++<li class="tocline">5. <a href="#issues">Compatibility Issues</a>++<ul class="toc">+<li class="tocline">5.1 <a href="#media">Internet Media Types</a></li>+</ul>+</li>++<li class="tocline">6. <a href="#future">Future Directions</a>++<ul class="toc">+<li class="tocline">6.1 <a href="#mods">Modularizing HTML</a></li>++<li class="tocline">6.2 <a href="#extensions">Subsets and Extensibility</a></li>++<li class="tocline">6.3 <a href="#profiles">Document Profiles</a></li>+</ul>+</li>++<li class="tocline"><a href="#dtds">Appendix A. DTDs</a></li>++<li class="tocline"><a href="#prohibitions">Appendix B. Element+Prohibitions</a></li>++<li class="tocline"><a href="#guidelines">Appendix C. HTML Compatibility Guidelines</a></li>++<li class="tocline"><a href="#acks">Appendix D. Acknowledgements</a></li>++<li class="tocline"><a href="#refs">Appendix E. References</a></li>+</ul>+</div>++<!--OddPage-->+<h1><a name="xhtml" id="xhtml">1. What is XHTML?</a></h1>++<p>XHTML is a family of current and future document types and modules that+reproduce, subset, and extend HTML 4 <a href="#ref-html4">[HTML]</a>. XHTML family document types are <abbr title="Extensible Markup Language">XML</abbr> based,+and ultimately are designed to work in conjunction with XML-based user agents.+The details of this family and its evolution are+discussed in more detail in the section on <a href="#future">Future+Directions</a>. </p>++<p>XHTML 1.0 (this specification) is the first document type in the XHTML+family. It is a reformulation of the three HTML 4 document types as+applications of XML 1.0 <a href="#ref-xml"> [XML]</a>. It is intended+to be used as a language for content that is both XML-conforming and, if some+simple <a href="#guidelines">guidelines</a> are followed,+operates in HTML 4 conforming user agents. Developers who migrate+their content to XHTML 1.0 will realize the following benefits:</p>++<ul>+<li>XHTML documents are XML conforming. As such, they are readily viewed,+edited, and validated with standard XML tools.</li>+<li>XHTML documents can be written to+to operate as well or better than they did before in existing+HTML 4-conforming user agents as well as in new, XHTML 1.0 conforming user+agents.</li>+<li>XHTML documents can utilize applications (e.g. scripts and applets) that rely+upon either the HTML Document Object Model or the XML Document Object Model <a+href="#ref-dom">[DOM]</a>.</li>+<li>As the XHTML family evolves, documents conforming to XHTML 1.0 will be more+likely to interoperate within and among various XHTML environments.</li>+</ul>++<p>The XHTML family is the next step in the evolution of the Internet. By+migrating to XHTML today, content developers can enter the XML world with all+of its attendant benefits, while still remaining confident in their+content's backward and future compatibility.</p>++<h2><a name="html4" id="html4">1.1 What is HTML 4?</a></h2>++<p>HTML 4 <a href="#ref-html4">[HTML]</a> is an <abbr title="Standard+Generalized Markup Language">SGML</abbr> (Standard+Generalized Markup Language) application conforming to+International Standard <abbr title="Organization for International+Standardization">ISO</abbr> 8879, and is widely regarded as the+standard publishing language of the World Wide Web.</p>++<p>SGML is a language for describing markup languages,+particularly those used in electronic document exchange, document+management, and document publishing. HTML is an example of a+language defined in SGML.</p>++<p>SGML has been around since the middle 1980's and has remained+quite stable. Much of this stability stems from the fact that the+language is both feature-rich and flexible. This flexibility,+however, comes at a price, and that price is a level of+complexity that has inhibited its adoption in a diversity of+environments, including the World Wide Web.</p>++<p>HTML, as originally conceived, was to be a language for the+exchange of scientific and other technical documents, suitable+for use by non-document specialists. HTML addressed the problem+of SGML complexity by specifying a small set of structural and+semantic tags suitable for authoring relatively simple documents.+In addition to simplifying the document structure, HTML added+support for hypertext. Multimedia capabilities were added+later.</p>++<p>In a remarkably short space of time, HTML became wildly+popular and rapidly outgrew its original purpose. Since HTML's+inception, there has been rapid invention of new elements for use+within HTML (as a standard) and for adapting HTML to vertical,+highly specialized, markets. This plethora of new elements has+led to compatibility problems for documents across different+platforms.</p>++<p>As the heterogeneity of both software and platforms rapidly+proliferate, it is clear that the suitability of 'classic' HTML 4+for use on these platforms is somewhat limited.</p>++<h2><a name="xml" id="xml">1.2 What is XML?</a></h2>++<p>XML<sup>™</sup> is the shorthand for Extensible Markup+Language, and is an acronym of Extensible Markup Language <a+href="#ref-xml">[XML]</a>.</p>++<p>XML was conceived as a means of regaining the power and+flexibility of SGML without most of its complexity. Although a+restricted form of SGML, XML nonetheless preserves most of SGML's+power and richness, and yet still retains all of SGML's commonly+used features.</p>++<p>While retaining these beneficial features, XML removes many of+the more complex features of SGML that make the authoring and+design of suitable software both difficult and costly.</p>++<h2><a name="why" id="why">1.3 Why the need for XHTML?</a></h2>++<p>The benefits of migrating to XHTML 1.0 are described above. Some of the+benefits of migrating to XHTML in general are:</p>++<ul>+<li>Document developers and user agent designers are constantly+discovering new ways to express their ideas through new markup. In XML, it is+relatively easy to introduce new elements or additional element+attributes. The XHTML family is designed to accommodate these extensions+through XHTML modules and techniques for developing new XHTML-conforming+modules (described in the forthcoming XHTML Modularization specification).+These modules will permit the combination of existing and+new feature sets when developing content and when designing new user+agents.</li>++<li>Alternate ways of accessing the Internet are constantly being+introduced. Some estimates indicate that by the year 2002, 75% of+Internet document viewing will be carried out on these alternate+platforms. The XHTML family is designed with general user agent+interoperability in mind. Through a new user agent and document profiling+mechanism, servers, proxies, and user agents will be able to perform+best effort content transformation. Ultimately, it will be possible to+develop XHTML-conforming content that is usable by any XHTML-conforming+user agent.</li>++</ul>+<!--OddPage-->+<h1><a name="defs" id="defs">2. Definitions</a></h1>++<h2><a name="terms" id="terms">2.1 Terminology</a></h2>++<p>The following terms are used in this specification. These+terms extend the definitions in <a href="#ref-rfc2119">+[RFC2119]</a> in ways based upon similar definitions in ISO/<abbr+title="International Electro-technical Commission">IEC</abbr>+9945-1:1990 <a href="#ref-posix">[POSIX.1]</a>:</p>++<dl>+<dt>Implementation-defined</dt>++<dd>A value or behavior is implementation-defined when it is left+to the implementation to define [and document] the corresponding+requirements for correct document construction.</dd>++<dt>May</dt>++<dd>With respect to implementations, the word "may" is to be+interpreted as an optional feature that is not required in this+specification but can be provided. With respect to <a href=+"#docconf">Document Conformance</a>, the word "may" means that+the optional feature must not be used. The term "optional" has+the same definition as "may".</dd>++<dt>Must</dt>++<dd>In this specification, the word "must" is to be interpreted+as a mandatory requirement on the implementation or on Strictly+Conforming XHTML Documents, depending upon the context. The term+"shall" has the same definition as "must".</dd>++<dt>Reserved</dt>++<dd>A value or behavior is unspecified, but it is not allowed to+be used by Conforming Documents nor to be supported by a+Conforming User Agents.</dd>++<dt>Should</dt>++<dd>With respect to implementations, the word "should" is to be+interpreted as an implementation recommendation, but not a+requirement. With respect to documents, the word "should" is to+be interpreted as recommended programming practice for documents+and a requirement for Strictly Conforming XHTML Documents.</dd>++<dt>Supported</dt>++<dd>Certain facilities in this specification are optional. If a+facility is supported, it behaves as specified by this+specification.</dd>++<dt>Unspecified</dt>++<dd>When a value or behavior is unspecified, the specification+defines no portability requirements for a facility on an+implementation even when faced with a document that uses the+facility. A document that requires specific behavior in such an+instance, rather than tolerating any behavior when using that+facility, is not a Strictly Conforming XHTML Document.</dd>+</dl>++<h2><a name="general" id="general">2.2 General Terms</a></h2>++<dl>+<dt>Attribute</dt>++<dd>An attribute is a parameter to an element declared in the+DTD. An attribute's type and value range, including a possible+default value, are defined in the DTD.</dd>++<dt>DTD</dt>++<dd>A DTD, or document type definition, is a collection of XML+declarations that, as a collection, defines the legal structure,+<span class="term">elements</span>, and <span class="term">+attributes</span> that are available for use in a document that+complies to the DTD.</dd>++<dt>Document</dt>++<dd>A document is a stream of data that, after being combined+with any other streams it references, is structured such that it+holds information contained within <span class="term">+elements</span> that are organized as defined in the associated+<span class="term">DTD</span>. See <a href="#docconf">Document+Conformance</a> for more information.</dd>++<dt>Element</dt>++<dd>An element is a document structuring unit declared in the+<span class="term">DTD</span>. The element's content model is+defined in the <span class="term">DTD</span>, and additional+semantics may be defined in the prose description of the+element.</dd>++<dt><a name="facilities" id="facilities">Facilities</a></dt>++<dd>Functionality includes <span class="term">elements</span>,+<span class="term">attributes</span>, and the semantics+associated with those <span class="term">elements</span> and+<span class="term">attributes</span>. An implementation+supporting that functionality is said to provide the necessary+facilities.</dd>++<dt>Implementation</dt>++<dd>An implementation is a system that provides collection of+<span class="term">facilities</span> and services that supports+this specification. See <a href="#uaconf">User Agent+Conformance</a> for more information.</dd>++<dt>Parsing</dt>++<dd>Parsing is the act whereby a <span class="term">+document</span> is scanned, and the information contained within+the <span class="term">document</span> is filtered into the+context of the <span class="term">elements</span> in which the+information is structured.</dd>++<dt>Rendering</dt>++<dd>Rendering is the act whereby the information in a <span+class="term">document</span> is presented. This presentation is+done in the form most appropriate to the environment (e.g.+aurally, visually, in print).</dd>++<dt>User Agent</dt>++<dd>A user agent is an <span class="term">implementation</span>+that retrieves and processes XHTML documents. See <a href=+"#uaconf">User Agent Conformance</a> for more information.</dd>++<dt>Validation</dt>++<dd>Validation is a process whereby <span class="term">+documents</span> are verified against the associated <span class=+"term">DTD</span>, ensuring that the structure, use of <span+class="term">elements</span>, and use of <span class="term">+attributes</span> are consistent with the definitions in the+<span class="term">DTD</span>.</dd>++<dt><a name="wellformed" id="wellformed">Well-formed</a></dt>++<dd>A <span class="term">document</span> is well-formed when it+is structured according to the rules defined in <a href=+"http://www.w3.org/TR/REC-xml#sec-well-formed">Section 2.1</a> of+the XML 1.0 Recommendation <a href="#ref-xml">[XML]</a>.+Basically, this definition states that elements, delimited by+their start and end tags, are nested properly within one+another.</dd>+</dl>++<!--OddPage-->+<h1><a name="normative" id="normative">3. Normative Definition of+XHTML 1.0</a></h1>++<h2><a name="docconf" id="docconf">3.1 Document+Conformance</a></h2>++<p>This version of XHTML provides a definition of strictly+conforming XHTML documents, which are restricted to tags and+attributes from the XHTML namespace. See <a href=+"#well-formed">Section 3.1.2</a> for information on using XHTML+with other namespaces, for instance, to include metadata+expressed in <abbr title="Resource Description Format">RDF</abbr> within XHTML documents.</p>++<h3><a name="strict" id="strict">3.1.1 Strictly Conforming+Documents</a></h3>++<p>A Strictly Conforming XHTML Document is a document that+requires only the facilities described as mandatory in this+specification. Such a document must meet all of the following+criteria:</p>++<ol>+<li>+<p>It must validate against one of the three DTDs found in <a+href="#dtds">Appendix A</a>.</p>+</li>++<li>+<p>The root element of the document must be <code>+<html></code>.</p>+</li>++<li>+<p>The root element of the document must designate the XHTML+namespace using the <code>xmlns</code> attribute <a href=+"#ref-xmlns">[XMLNAMES]</a>. The namespace for XHTML is+defined to be+<code>http://www.w3.org/1999/xhtml</code>.</p>+</li>++<li>+<p>There must be a DOCTYPE declaration in the document prior to+the root element. The public identifier included in+the DOCTYPE declaration must reference one of the three DTDs+found in <a href="#dtds">Appendix A</a> using the respective+Formal Public Identifier. The system identifier may be changed to reflect+local system conventions.</p>++<pre>+<!DOCTYPE html+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"+ "DTD/xhtml1-strict.dtd">++<!DOCTYPE html+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"+ "DTD/xhtml1-transitional.dtd">++<!DOCTYPE html+ PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"+ "DTD/xhtml1-frameset.dtd">+</pre>+</li>+</ol>++<p>Here is an example of a minimal XHTML document.</p>++<div class="good">+<pre>+<?xml version="1.0" encoding="UTF-8"?>+<!DOCTYPE html+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"+ "DTD/xhtml1-strict.dtd">+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">+ <head>+ <title>Virtual Library</title>+ </head>+ <body>+ <p>Moved to <a href="http://vlib.org/">vlib.org</a>.</p>+ </body>+</html></pre>+</div>++<p>Note that in this example, the XML declaration is included. An XML+declaration like the one above is+not required in all XML documents. XHTML document authors are strongly encouraged to use XML declarations in all their documents. Such a declaration is required+when the character encoding of the document is other than the default UTF-8 or+UTF-16.</p>++<h3><a name="well-formed" id="well-formed">3.1.2 Using XHTML with+other namespaces</a></h3>++<p>The XHTML namespace may be used with other XML namespaces+as per <a href="#ref-xmlns">[XMLNAMES]</a>, although such+documents are not strictly conforming XHTML 1.0 documents as+defined above. Future work by W3C will address ways to specify+conformance for documents involving multiple namespaces.</p>++<p>The following example shows the way in which XHTML 1.0 could+be used in conjunction with the MathML Recommendation:</p>++<div class="good">+<pre>+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">+ <head>+ <title>A Math Example</title>+ </head>+ <body>+ <p>The following is MathML markup:</p>+ <math xmlns="http://www.w3.org/1998/Math/MathML">+ <apply> <log/>+ <logbase>+ <cn> 3 </cn>+ </logbase>+ <ci> x </ci>+ </apply>+ </math>+ </body>+</html>+</pre>+</div>++<p>The following example shows the way in which XHTML 1.0 markup+could be incorporated into another XML namespace:</p>++<div class="good">+<pre>+<?xml version="1.0" encoding="UTF-8"?>+<!-- initially, the default namespace is "books" -->+<book xmlns='urn:loc.gov:books'+ xmlns:isbn='urn:ISBN:0-395-36341-6' xml:lang="en" lang="en">+ <title>Cheaper by the Dozen</title>+ <isbn:number>1568491379</isbn:number>+ <notes>+ <!-- make HTML the default namespace for a hypertext commentary -->+ <p xmlns='http://www.w3.org/1999/xhtml'>+ This is also available <a href="http://www.w3.org/">online</a>.+ </p>+ </notes>+</book>+</pre>+</div>++<h2><a name="uaconf" id="uaconf">3.2 User Agent+Conformance</a></h2>++<p>A conforming user agent must meet all of the following+criteria:</p>++<ol>+<li>In order to be consistent with the XML 1.0 Recommendation <a+href="#ref-xml">[XML]</a>, the user agent must parse and evaluate+an XHTML document for well-formedness. If the user agent claims+to be a validating user agent, it must also validate documents+against their referenced DTDs according to <a href="#ref-xml">+[XML]</a>.</li>++<li>When the user agent claims to support <a href="#facilities">+facilities</a> defined within this specification or required by+this specification through normative reference, it must do so in+ways consistent with the facilities' definition.</li>++<li>When a user agent processes an XHTML document as generic XML,+it shall only recognize attributes of type+<code>ID</code> (e.g. the <code>id</code> attribute on most XHTML elements)+as fragment identifiers.</li>++<li>If a user agent encounters an element it does not recognize,+it must render the element's content.</li>++<li>If a user agent encounters an attribute it does not+recognize, it must ignore the entire attribute specification+(i.e., the attribute and its value).</li>++<li>If a user agent encounters an attribute value it doesn't+recognize, it must use the default attribute value.</li>++<li>If it encounters an entity reference (other than one+of the predefined entities) for which the User Agent has+processed no declaration (which could happen if the declaration+is in the external subset which the User Agent hasn't read), the entity+reference should be rendered as the characters (starting+with the ampersand and ending with the semi-colon) that+make up the entity reference.</li>++<li>When rendering content, User Agents that encounter+characters or character entity references that are recognized but not renderable should display the document in such a way that it is obvious to the user that normal rendering has not taken place.</li>++<li>+The following characters are defined in [XML] as whitespace characters:++<ul>+<li>Space (&#x0020;)</li>+<li>Tab (&#x0009;)</li>+<li>Carriage return (&#x000D;)</li>+<li>Line feed (&#x000A;)</li>+</ul>++<p>+The XML processor normalizes different system's line end codes into one+single line-feed character, that is passed up to the application. The XHTML+user agent in addition, must treat the following characters as whitespace:+</p>++<ul>+<li>Form feed (&#x000C;)</li>+<li>Zero-width space (&#x200B;)</li>+</ul>++<p>+In elements where the 'xml:space' attribute is set to 'preserve', the user+agent must leave all whitespace characters intact (with the exception of+leading and trailing whitespace characters, which should be removed).+Otherwise, whitespace+is handled according to the following rules:+</p>++<ul>+<li>+All whitespace surrounding block elements should be removed.+</li>+<li>+Comments are removed entirely and do not affect whitespace handling. One+whitespace character on either side of a comment is treated as two white+space characters.+</li>+<li>+Leading and trailing whitespace inside a block element must be removed.+</li>+<li>Line feed characters within a block element must be converted into a+space (except when the 'xml:space' attribute is set to 'preserve').+</li>+<li>+A sequence of white space characters must be reduced to a single space+character (except when the 'xml:space' attribute is set to 'preserve').+</li>+<li>+With regard to rendition,+the User Agent should render the content in a+manner appropriate to the language in which the content is written.+In languages whose primary script is Latinate, the ASCII space+character is typically used to encode both grammatical word boundaries and+typographic whitespace; in languages whose script is related to Nagari+(e.g., Sanskrit, Thai, etc.), grammatical boundaries may be encoded using+the ZW 'space' character, but will not typically be represented by+typographic whitespace in rendered output; languages using Arabiform scripts+may encode typographic whitespace using a space character, but may also use+the ZW space character to delimit 'internal' grammatical boundaries (what+look like words in Arabic to an English eye frequently encode several words,+e.g. 'kitAbuhum' = 'kitAbu-hum' = 'book them' == their book); and languages+in the Chinese script tradition typically neither encode such delimiters nor+use typographic whitespace in this way.+</li>+</ul>++<p>Whitespace in attribute values is processed according to <a+href="#ref-xml">[XML]</a>.</p>+</li>+</ol>++<!--OddPage-->+<h1><a name="diffs" id="diffs">4. Differences with HTML 4</a></h1>++<p>Due to the fact that XHTML is an XML application, certain+practices that were perfectly legal in SGML-based HTML 4 <a+href="#ref-html4">[HTML]</a> must be changed.</p>++<h2><a name="h-4.1" id="h-4.1">4.1 Documents must be+well-formed</a></h2>++<p><a href="#wellformed">Well-formedness</a> is a new concept+introduced by <a href="#ref-xml">[XML]</a>. Essentially this+means that all elements must either have closing tags or be+written in a special form (as described below), and that all the+elements must nest.</p>++<p>Although overlapping is illegal in SGML, it was widely+tolerated in existing browsers.</p>++<div class="good">+<p><strong><em>CORRECT: nested elements.</em></strong></p>++<p><p>here is an emphasized+<em>paragraph</em>.</p></p>+</div>++<div class="bad">+<p><strong><em>INCORRECT: overlapping elements</em></strong></p>++<p><p>here is an emphasized+<em>paragraph.</p></em></p>+</div>++<h2><a name="h-4.2" id="h-4.2">4.2 Element and attribute+names must be in lower case</a></h2>++<p>XHTML documents must use lower case for all HTML element and+attribute names. This difference is necessary because XML is+case-sensitive e.g. <li> and <LI> are different+tags.</p>++<h2><a name="h-4.3" id="h-4.3">4.3 For non-empty elements,+end tags are required</a></h2>++<p>In SGML-based HTML 4 certain elements were permitted to omit+the end tag; with the elements that followed implying closure.+This omission is not permitted in XML-based XHTML. All elements+other than those declared in the DTD as <code>EMPTY</code> must+have an end tag.</p>++<div class="good">+<p><strong><em>CORRECT: terminated elements</em></strong></p>++<p><p>here is a paragraph.</p><p>here is+another paragraph.</p></p>+</div>++<div class="bad">+<p><strong><em>INCORRECT: unterminated elements</em></strong></p>++<p><p>here is a paragraph.<p>here is another+paragraph.</p>+</div>++<h2><a name="h-4.4" id="h-4.4">4.4 Attribute values must+always be quoted</a></h2>++<p>All attribute values must be quoted, even those which appear+to be numeric.</p>++<div class="good">+<p><strong><em>CORRECT: quoted attribute values</em></strong></p>++<p><table rows="3"></p>+</div>++<div class="bad">+<p><strong><em>INCORRECT: unquoted attribute values</em></strong></p>++<p><table rows=3></p>+</div>++<h2><a name="h-4.5" id="h-4.5">4.5 Attribute+Minimization</a></h2>++<p>XML does not support attribute minimization. Attribute-value+pairs must be written in full. Attribute names such as <code>+compact</code> and <code>checked</code> cannot occur in elements+without their value being specified.</p>++<div class="good">+<p><strong><em>CORRECT: unminimized attributes</em></strong></p>++<p><dl compact="compact"></p>+</div>++<div class="bad">+<p><strong><em>INCORRECT: minimized attributes</em></strong></p>++<p><dl compact></p>+</div>++<h2><a name="h-4.6" id="h-4.6">4.6 Empty Elements</a></h2>++<p>Empty elements must either have an end tag or the start tag must end with <code>/></code>. For instance,+<code><br/></code> or <code><hr></hr></code>. See <a+href="#guidelines">HTML Compatibility Guidelines</a> for information on ways to+ensure this is backward compatible with HTML 4 user agents.</p>++<div class="good">+<p><strong><em>CORRECT: terminated empty tags</em></strong></p>++<p><br/><hr/></p>+</div>++<div class="bad">+<p><strong><em>INCORRECT: unterminated empty tags</em></strong></p>++<p><br><hr></p>+</div>++<h2><a name="h-4.7" id="h-4.7">4.7 Whitespace handling in+attribute values</a></h2>++<p>In attribute values, user agents will strip leading and+trailing whitespace from attribute values and map sequences+of one or more whitespace characters (including line breaks) to+a single inter-word space (an ASCII space character for western+scripts). See <a href="http://www.w3.org/TR/REC-xml#AVNormalize">+Section 3.3.3</a> of <a href="#ref-xml">[XML]</a>.</p>++<h2><a name="h-4.8" id="h-4.8">4.8 Script and Style+elements</a></h2>++<p>In XHTML, the script and style elements are declared as having+<code>#PCDATA</code> content. As a result, <code><</code> and+<code>&</code> will be treated as the start of markup, and+entities such as <code>&lt;</code> and <code>&amp;</code>+will be recognized as entity references by the XML processor to+<code><</code> and <code>&</code> respectively. Wrapping+the content of the script or style element within a <code>+CDATA</code> marked section avoids the expansion of these+entities.</p>++<div class="good">+<pre>+<script>+ <![CDATA[+ ... unescaped script content ...+ ]]>+ </script>+</pre>+</div>++<p><code>CDATA</code> sections are recognized by the XML+processor and appear as nodes in the Document Object Model, see+<a href=+"http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-E067D597">+Section 1.3</a> of the DOM Level 1 Recommendation <a href=+"#ref-dom">[DOM]</a>.</p>++<p>An alternative is to use external script and style+documents.</p>++<h2><a name="h-4.9" id="h-4.9">4.9 SGML exclusions</a></h2>++<p>SGML gives the writer of a DTD the ability to exclude specific+elements from being contained within an element. Such+prohibitions (called "exclusions") are not possible in XML.</p>++<p>For example, the HTML 4 Strict DTD forbids the nesting of an+'<code>a</code>' element within another '<code>a</code>' element+to any descendant depth. It is not possible to spell out such+prohibitions in XML. Even though these prohibitions cannot be+defined in the DTD, certain elements should not be nested. A+summary of such elements and the elements that should not be+nested in them is found in the normative <a href="#prohibitions">+Appendix B</a>.</p>++<h2><a name="h-4.10" id="h-4.10">4.10 The elements with 'id' and 'name'+attributes</a></h2>++<p>HTML 4 defined the <code>name</code> attribute for the elements+<code>a</code>,+<code>applet</code>, <code>form</code>, <code>frame</code>,+<code>iframe</code>, <code>img</code>, and <code>map</code>.+HTML 4 also introduced+the <code>id</code> attribute. Both of these attributes are designed to be+used as fragment identifiers.</p>+<p>In XML, fragment identifiers are of type <code>ID</code>, and+there can only be a single attribute of type <code>ID</code> per element.+Therefore, in XHTML 1.0 the <code>id</code>+attribute is defined to be of type <code>ID</code>. In order to+ensure that XHTML 1.0 documents are well-structured XML documents, XHTML 1.0+documents MUST use the <code>id</code> attribute when defining fragment+identifiers, even on elements that historically have also had a+<code>name</code> attribute.+See the <a href="#guidelines">HTML Compatibility+Guidelines</a> for information on ensuring such anchors are backwards+compatible when serving XHTML documents as media type <code>text/html</code>.+</p>+<p>Note that in XHTML 1.0, the <code>name</code> attribute of these+elements is formally deprecated, and will be removed in a+subsequent version of XHTML.</p>++<!--OddPage-->+<h1><a name="issues" id="issues">5. Compatibility Issues</a></h1>++<p>Although there is no requirement for XHTML 1.0 documents to be+compatible with existing user agents, in practice this is easy to+accomplish. Guidelines for creating compatible documents can be+found in <a href="#guidelines">Appendix C</a>.</p>++<h2><a name="media" id="media">5.1 Internet Media Type</a></h2>+<p>As of the publication of this recommendation, the general+recommended MIME labeling for XML-based applications+has yet to be resolved.</p>++<p>However, XHTML Documents which follow the guidelines set forth+in <a href="#guidelines">Appendix C</a>, "HTML Compatibility Guidelines" may be+labeled with the Internet Media Type "text/html", as they+are compatible with most HTML browsers. This document+makes no recommendation about MIME labeling of other+XHTML documents.</p>++<!--OddPage-->+<h1><a name="future" id="future">6. Future Directions</a></h1>++<p>XHTML 1.0 provides the basis for a family of document types+that will extend and subset XHTML, in order to support a wide+range of new devices and applications, by defining modules and+specifying a mechanism for combining these modules. This+mechanism will enable the extension and sub-setting of XHTML 1.0+in a uniform way through the definition of new modules.</p>++<h2><a name="mods" id="mods">6.1 Modularizing HTML</a></h2>++<p>As the use of XHTML moves from the traditional desktop user+agents to other platforms, it is clear that not all of the XHTML+elements will be required on all platforms. For example a hand+held device or a cell-phone may only support a subset of XHTML+elements.</p>++<p>The process of modularization breaks XHTML up into a series of+smaller element sets. These elements can then be recombined to+meet the needs of different communities.</p>++<p>These modules will be defined in a later W3C document.</p>++<h2><a name="extensions" id="extensions">6.2 Subsets and+Extensibility</a></h2>++<p>Modularization brings with it several advantages:</p>++<ul>+<li>+<p>It provides a formal mechanism for sub-setting XHTML.</p>+</li>++<li>+<p>It provides a formal mechanism for extending XHTML.</p>+</li>++<li>+<p>It simplifies the transformation between document types.</p>+</li>++<li>+<p>It promotes the reuse of modules in new document types.</p>+</li>+</ul>++<h2><a name="profiles" id="profiles">6.3 Document+Profiles</a></h2>++<p>A document profile specifies the syntax and semantics of a set+of documents. Conformance to a document profile provides a basis+for interoperability guarantees. The document profile specifies+the facilities required to process documents of that type, e.g.+which image formats can be used, levels of scripting, style sheet+support, and so on.</p>++<p>For product designers this enables various groups to define+their own standard profile.</p>++<p>For authors this will obviate the need to write several+different versions of documents for different clients.</p>++<p>For special groups such as chemists, medical doctors, or+mathematicians this allows a special profile to be built using+standard HTML elements plus a group of elements geared to the+specialist's needs.</p>++<!--OddPage-->+<h1><a name="appendices" id="appendices"></a>+<a name="dtds" id="dtds">Appendix A. DTDs</a></h1>++<p><b>This appendix is normative.</b></p>++<p>These DTDs and entity sets form a normative part of this+specification. The complete set of DTD files together with an XML+declaration and SGML Open Catalog is included in the <a href=+"xhtml1.zip">zip file</a> for this specification.</p>++<h2><a name="h-A1" id="h-A1">A.1 Document Type+Definitions</a></h2>++<p>These DTDs approximate the HTML 4 DTDs. It is likely that+when the DTDs are modularized, a method of DTD construction will+be employed that corresponds more closely to HTML 4.</p>++<ul>+<li>+<p><a href="DTD/xhtml1-strict.dtd" type="text/plain">+XHTML-1.0-Strict</a></p>+</li>++<li>+<p><a href="DTD/xhtml1-transitional.dtd" type="text/plain">+XHTML-1.0-Transitional</a></p>+</li>++<li>+<p><a href="DTD/xhtml1-frameset.dtd" type="text/plain">+XHTML-1.0-Frameset</a></p>+</li>+</ul>++<h2><a name="h-A2" id="h-A2">A.2 Entity Sets</a></h2>++<p>The XHTML entity sets are the same as for HTML 4, but have+been modified to be valid XML 1.0 entity declarations. Note the+entity for the Euro currency sign (<code>&euro;</code> or+<code>&#8364;</code> or <code>&#x20AC;</code>) is defined+as part of the special characters.</p>++<ul>+<li>+<p><a href="DTD/xhtml-lat1.ent">Latin-1 characters</a></p>+</li>++<li>+<p><a href="DTD/xhtml-special.ent">Special characters</a></p>+</li>++<li>+<p><a href="DTD/xhtml-symbol.ent">Symbols</a></p>+</li>+</ul>++<!--OddPage-->+<h1><a name="prohibitions" id="prohibitions">Appendix B. Element+Prohibitions</a></h1>++<p><b>This appendix is normative.</b></p>++<p>The following elements have prohibitions on which elements+they can contain (see <a href="#h-4.9">Section 4.9</a>). This+prohibition applies to all depths of nesting, i.e. it contains+all the descendant elements.</p>++<dl><dt><code class="tag">a</code></dt>+<dd>+cannot contain other <code>a</code> elements.</dd>+<dt><code class="tag">pre</code></dt>+<dd>cannot contain the <code>img</code>, <code>object</code>,+<code>big</code>, <code>small</code>, <code>sub</code>, or <code>+sup</code> elements.</dd>++<dt><code class="tag">button</code></dt>+<dd>cannot contain the <code>input</code>, <code>select</code>,+<code>textarea</code>, <code>label</code>, <code>button</code>,+<code>form</code>, <code>fieldset</code>, <code>iframe</code> or+<code>isindex</code> elements.</dd>+<dt><code class="tag">label</code></dt>+<dd>cannot contain other <code class="tag">label</code> elements.</dd>+<dt><code class="tag">form</code></dt>+<dd>cannot contain other <code>form</code> elements.</dd>+</dl>++<!--OddPage-->+<h1><a name="guidelines" id="guidelines">Appendix C.+HTML Compatibility Guidelines</a></h1>++<p><b>This appendix is informative.</b></p>++<p>This appendix summarizes design guidelines for authors who+wish their XHTML documents to render on existing HTML user+agents.</p>++<h2>C.1 Processing Instructions</h2>+<p>Be aware that processing instructions are rendered on some+user agents. However, also note that when the XML declaration is not included+in a document, the document can only use the default character encodings UTF-8+or UTF-16.</p>++<h2>C.2 Empty Elements</h2>+<p>Include a space before the trailing <code>/</code> and <code>+></code> of empty elements, e.g. <code class="greenmono">+<br /></code>, <code class="greenmono">+<hr /></code> and <code class="greenmono"><img+src="karen.jpg" alt="Karen" /></code>. Also, use the+minimized tag syntax for empty elements, e.g. <code class=+"greenmono"><br /></code>, as the alternative syntax <code+class="greenmono"><br></br></code> allowed by XML+gives uncertain results in many existing user agents.</p>++<h2>C.3 Element Minimization and Empty Element Content</h2>+<p>Given an empty instance of an element whose content model is+not <code>EMPTY</code> (for example, an empty title or paragraph)+do not use the minimized form (e.g. use <code class="greenmono">+<p> </p></code> and not <code class="greenmono">+<p /></code>).</p>++<h2>C.4 Embedded Style Sheets and Scripts</h2>+<p>Use external style sheets if your style sheet uses <code>+<</code> or <code>&</code> or <code>]]></code> or <code>--</code>. Use+external scripts if your script uses <code><</code> or <code>+&</code> or <code>]]></code> or <code>--</code>. Note that XML parsers+are permitted to silently remove the contents of comments. Therefore, the historical+practice of "hiding" scripts and style sheets within comments to make the+documents backward compatible is likely to not work as expected in XML-based+implementations.</p>++<h2>C.5 Line Breaks within Attribute Values</h2>+<p>Avoid line breaks and multiple whitespace characters within+attribute values. These are handled inconsistently by user+agents.</p>++<h2>C.6 Isindex</h2>+<p>Don't include more than one <code>isindex</code> element in+the document <code>head</code>. The <code>isindex</code> element+is deprecated in favor of the <code>input</code> element.</p>++<h2>C.7 The <code>lang</code> and <code>xml:lang</code> Attributes</h2>+<p>Use both the <code>lang</code> and <code>xml:lang</code>+attributes when specifying the language of an element. The value+of the <code>xml:lang</code> attribute takes precedence.</p>++<h2>C.8 Fragment Identifiers</h2>+<p>In XML, <abbr title="Uniform Resource Identifiers">URIs</abbr> [<a href="#ref-rfc2396">RFC2396</a>] that end with fragment identifiers of the form+<code>"#foo"</code> do not refer to elements with an attribute+<code>name="foo"</code>; rather, they refer to elements with an+attribute defined to be of type <code>ID</code>, e.g., the <code>+id</code> attribute in HTML 4. Many existing HTML clients don't+support the use of <code>ID</code>-type attributes in this way,+so identical values may be supplied for both of these attributes to ensure+maximum forward and backward compatibility (e.g., <code class=+"greenmono"><a id="foo" name="foo">...</a></code>).</p>++<p>Further, since the set of+legal values for attributes of type <code>ID</code> is much smaller than+for those of type <code>CDATA</code>, the type of the <code>name</code>+attribute has been changed to <code>NMTOKEN</code>. This attribute is+constrained such that it can only have the same values as type+<code>ID</code>, or as the <code>Name</code> production in XML 1.0 Section+2.5, production 5. Unfortunately, this constraint cannot be expressed in the+XHTML 1.0 DTDs. Because of this change, care must be taken when+converting existing HTML documents. The values of these attributes+must be unique within the document, valid, and any references to these+fragment identifiers (both+internal and external) must be updated should the values be changed during+conversion.</p>+<p>Finally, note that XHTML 1.0 has deprecated the+<code>name</code> attribute of the <code>a</code>, <code>applet</code>, <code>form</code>, <code>frame</code>, <code>iframe</code>, <code>img</code>, and <code>map</code>+elements, and it will be+removed from XHTML in subsequent versions.</p>++<h2>C.9 Character Encoding</h2>+<p>To specify a character encoding in the document, use both the+encoding attribute specification on the xml declaration (e.g.+<code class="greenmono"><?xml version="1.0"+encoding="EUC-JP"?></code>) and a meta http-equiv statement+(e.g. <code class="greenmono"><meta http-equiv="Content-type"+content='text/html; charset="EUC-JP"' /></code>). The+value of the encoding attribute of the xml processing instruction+takes precedence.</p>++<h2>C.10 Boolean Attributes</h2>+<p>Some HTML user agents are unable to interpret boolean+attributes when these appear in their full (non-minimized) form,+as required by XML 1.0. Note this problem doesn't affect user+agents compliant with HTML 4. The following attributes are+involved: <code>compact</code>, <code>nowrap</code>, <code>+ismap</code>, <code>declare</code>, <code>noshade</code>, <code>+checked</code>, <code>disabled</code>, <code>readonly</code>,+<code>multiple</code>, <code>selected</code>, <code>+noresize</code>, <code>defer</code>.</p>++<h2>C.11 Document Object Model and XHTML</h2>+<p>+The Document Object Model level 1 Recommendation [<a href="#ref-dom">DOM</a>]+defines document object model interfaces for XML and HTML 4. The HTML 4+document object model specifies that HTML element and attribute names are+returned in upper-case. The XML document object model specifies that+element and attribute names are returned in the case they are specified. In+XHTML 1.0, elements and attributes are specified in lower-case. This apparent difference can be+addressed in two ways:+</p>+<ol>+<li>Applications that access XHTML documents served as Internet media type+<code>text/html</code>+via the <abbr title="Document Object Model">DOM</abbr> can use the HTML DOM,+and can rely upon element and attribute names being returned in+upper-case from those interfaces.</li>+<li>Applications that access XHTML documents served as Internet media types+<code>text/xml</code> or <code>application/xml</code>+can also use the XML DOM. Elements and attributes will be returned in lower-case.+Also, some XHTML elements may or may+not appear+in the object tree because they are optional in the content model+(e.g. the <code>tbody</code> element within+<code>table</code>). This occurs because in HTML 4 some elements were+permitted to be minimized such that their start and end tags are both omitted+(an SGML feature).+This is not possible in XML. Rather than require document authors to insert+extraneous elements, XHTML has made the elements optional.+Applications need to adapt to this+accordingly.</li>+</ol>++<h2>C.12 Using Ampersands in Attribute Values</h2>+<p>+When an attribute value contains an ampersand, it must be expressed as a character+entity reference+(e.g. "<code>&amp;</code>"). For example, when the+<code>href</code> attribute+of the <code>a</code> element refers to a+CGI script that takes parameters, it must be expressed as+<code>http://my.site.dom/cgi-bin/myscript.pl?class=guest&amp;name=user</code>+rather than as+<code>http://my.site.dom/cgi-bin/myscript.pl?class=guest&name=user</code>.+</p>++<h2>C.13 Cascading Style Sheets (CSS) and XHTML</h2>++<p>The Cascading Style Sheets level 2 Recommendation [<a href="#ref-css2">CSS2</a>] defines style+properties which are applied to the parse tree of the HTML or XML+document. Differences in parsing will produce different visual or+aural results, depending on the selectors used. The following hints+will reduce this effect for documents which are served without+modification as both media types:</p>++<ol>+<li>+CSS style sheets for XHTML should use lower case element and+attribute names.</li>+++<li>In tables, the tbody element will be inferred by the parser of an+HTML user agent, but not by the parser of an XML user agent. Therefore+you should always explicitly add a tbody element if it is referred to+in a CSS selector.</li>++<li>Within the XHTML name space, user agents are expected to+recognize the "id" attribute as an attribute of type ID.+Therefore, style sheets should be able to continue using the+shorthand "#" selector syntax even if the user agent does not read+the DTD.</li>++<li>Within the XHTML name space, user agents are expected to+recognize the "class" attribute. Therefore, style sheets should be+able to continue using the shorthand "." selector syntax.</li>++<li>+CSS defines different conformance rules for HTML and XML documents;+be aware that the HTML rules apply to XHTML documents delivered as+HTML and the XML rules apply to XHTML documents delivered as XML.</li>+</ol>+<!--OddPage-->+<h1><a name="acks" id="acks">Appendix D.+Acknowledgements</a></h1>++<p><b>This appendix is informative.</b></p>++<p>This specification was written with the participation of the+members of the W3C HTML working group:</p>++<dl>+<dd>Steven Pemberton, CWI (HTML Working Group Chair)<br />+Murray Altheim, Sun Microsystems<br />+Daniel Austin, AskJeeves (CNET: The Computer Network through July 1999)<br />+Frank Boumphrey, HTML Writers Guild<br />+John Burger, Mitre<br />+Andrew W. Donoho, IBM<br />+Sam Dooley, IBM<br />+Klaus Hofrichter, GMD<br />+Philipp Hoschka, W3C<br />+Masayasu Ishikawa, W3C<br />+Warner ten Kate, Philips Electronics<br />+Peter King, Phone.com<br />+Paula Klante, JetForm<br />+Shin'ichi Matsui, Panasonic (W3C visiting engineer through September 1999)<br />+Shane McCarron, Applied Testing and Technology (The Open Group through August+1999)<br />+Ann Navarro, HTML Writers Guild<br />+Zach Nies, Quark<br />+Dave Raggett, W3C/HP (W3C lead for HTML)<br />+Patrick Schmitz, Microsoft<br />+Sebastian Schnitzenbaumer, Stack Overflow<br />+Peter Stark, Phone.com<br />+Chris Wilson, Microsoft<br />+Ted Wugofski, Gateway 2000<br />+Dan Zigmond, WebTV Networks</dd>+</dl>++<!--OddPage-->+<h1><a name="refs" id="refs">Appendix E. References</a></h1>++<p><b>This appendix is informative.</b></p>++<dl>++<dt><a name="ref-css2" id="ref-css2"><b>[CSS2]</b></a></dt>++<dd><a href="http://www.w3.org/TR/1998/REC-CSS2-19980512">"Cascading Style Sheets, level 2 (CSS2) Specification"</a>, B.+Bos, H. W. Lie, C. Lilley, I. Jacobs, 12 May 1998.<br />+Latest version available at: <a href="http://www.w3.org/TR/REC-CSS2">+http://www.w3.org/TR/REC-CSS2</a></dd>++<dt><a name="ref-dom" id="ref-dom"><b>[DOM]</b></a></dt>++<dd><a href="http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001">"Document Object Model (DOM) Level 1 Specification"</a>, Lauren+Wood <i>et al.</i>, 1 October 1998.<br />+Latest version available at: <a href="http://www.w3.org/TR/REC-DOM-Level-1">+http://www.w3.org/TR/REC-DOM-Level-1</a></dd>++<dt><a name="ref-html4" id="ref-html4"><b>[HTML]</b></a></dt>++<dd><a href="http://www.w3.org/TR/1999/REC-html401-19991224">"HTML 4.01 Specification"</a>, D. Raggett, A. Le Hors, I.+Jacobs, 24 December 1999.<br />+Latest version available at: <a href="http://www.w3.org/TR/html401">+http://www.w3.org/TR/html401</a></dd>++<dt><a name="ref-posix" id="ref-posix"><b>[POSIX.1]</b></a></dt>++<dd>"ISO/IEC 9945-1:1990 Information Technology - Portable+Operating System Interface (POSIX) - Part 1: System Application+Program Interface (API) [C Language]", Institute of Electrical+and Electronics Engineers, Inc, 1990.</dd>++<dt><a name="ref-rfc2046" id="ref-rfc2046"><b>+[RFC2046]</b></a></dt>++<dd><a href="http://www.ietf.org/rfc/rfc2046.txt">"RFC2046: Multipurpose Internet Mail Extensions (MIME) Part+Two: Media Types"</a>, N. Freed and N. Borenstein, November+1996.<br />+Available at <a href="http://www.ietf.org/rfc/rfc2046.txt">+http://www.ietf.org/rfc/rfc2046.txt</a>. Note that this RFC+obsoletes RFC1521, RFC1522, and RFC1590.</dd>++<dt><a name="ref-rfc2119" id="ref-rfc2119"><b>+[RFC2119]</b></a></dt>++<dd><a href="http://www.ietf.org/rfc/rfc2119.txt">"RFC2119: Key words for use in RFCs to Indicate Requirement+Levels"</a>, S. Bradner, March 1997.<br />+Available at: <a href="http://www.ietf.org/rfc/rfc2119.txt">+http://www.ietf.org/rfc/rfc2119.txt</a></dd>++<dt><a name="ref-rfc2376" id="ref-rfc2376"><b>+[RFC2376]</b></a></dt>++<dd><a href="http://www.ietf.org/rfc/rfc2376.txt">"RFC2376: XML Media Types"</a>, E. Whitehead, M. Murata, July+1998.<br />+Available at: <a href="http://www.ietf.org/rfc/rfc2376.txt">+http://www.ietf.org/rfc/rfc2376.txt</a></dd>++<dt><a name="ref-rfc2396" id="ref-rfc2396"><b>+[RFC2396]</b></a></dt>++<dd><a href="http://www.ietf.org/rfc/rfc2396.txt">"RFC2396: Uniform Resource Identifiers (URI): Generic+Syntax"</a>, T. Berners-Lee, R. Fielding, L. Masinter, August+1998.<br />+This document updates RFC1738 and RFC1808.<br />+Available at: <a href="http://www.ietf.org/rfc/rfc2396.txt">+http://www.ietf.org/rfc/rfc2396.txt</a></dd>++<dt><a name="ref-xml" id="ref-xml"><b>[XML]</b></a></dt>++<dd><a href="http://www.w3.org/TR/1998/REC-xml-19980210">"Extensible Markup Language (XML) 1.0 Specification"</a>, T.+Bray, J. Paoli, C. M. Sperberg-McQueen, 10 February 1998.<br />+Latest version available at: <a href="http://www.w3.org/TR/REC-xml">+http://www.w3.org/TR/REC-xml</a></dd>++<dt><a name="ref-xmlns" id="ref-xmlns"><b>[XMLNAMES]</b></a></dt>++<dd><a href="http://www.w3.org/TR/1999/REC-xml-names-19990114">"Namespaces in XML"</a>, T. Bray, D. Hollander, A. Layman, 14+January 1999.<br />+XML namespaces provide a simple method for qualifying names used+in XML documents by associating them with namespaces identified+by URI.<br />+Latest version available at: <a href="http://www.w3.org/TR/REC-xml-names">+http://www.w3.org/TR/REC-xml-names</a></dd>++</dl>+<p><a href="http://www.w3.org/WAI/WCAG1AAA-Conformance"+title="Explanation of Level Triple-A Conformance">+<img height="32" width="88"+src="http://www.w3.org/WAI/wcag1AAA.gif"+alt="Level Triple-A conformance icon, W3C-WAI Web Content Accessibility Guidelines 1.0" /></a></p>+<div class="navbar">+ <hr />+ <a href="#toc">table of contents</a>+</div>+</body>+</html>+
+ examples/hxpath/xhtml/xhtml1-frameset.dtd view
@@ -0,0 +1,1225 @@+<!--+ Extensible HTML version 1.0 Frameset DTD++ This is the same as HTML 4.0 Frameset except for+ changes due to the differences between XML and SGML.++ Namespace = http://www.w3.org/1999/xhtml++ For further information, see: http://www.w3.org/TR/xhtml1++ Copyright (c) 1998-2000 W3C (MIT, INRIA, Keio),+ All Rights Reserved. ++ This DTD module is identified by the PUBLIC and SYSTEM identifiers:++ PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"+ SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"++ $Revision: 1.1 $+ $Date: 2002/10/01 13:47:08 $++-->++<!--================ Character mnemonic entities =========================-->++<!ENTITY % HTMLlat1 PUBLIC+ "-//W3C//ENTITIES Latin 1 for XHTML//EN"+ "xhtml-lat1.ent">+%HTMLlat1;++<!ENTITY % HTMLsymbol PUBLIC+ "-//W3C//ENTITIES Symbols for XHTML//EN"+ "xhtml-symbol.ent">+%HTMLsymbol;++<!ENTITY % HTMLspecial PUBLIC+ "-//W3C//ENTITIES Special for XHTML//EN"+ "xhtml-special.ent">+%HTMLspecial;++<!--================== Imported Names ====================================-->++<!ENTITY % ContentType "CDATA">+ <!-- media type, as per [RFC2045] -->++<!ENTITY % ContentTypes "CDATA">+ <!-- comma-separated list of media types, as per [RFC2045] -->++<!ENTITY % Charset "CDATA">+ <!-- a character encoding, as per [RFC2045] -->++<!ENTITY % Charsets "CDATA">+ <!-- a space separated list of character encodings, as per [RFC2045] -->++<!ENTITY % LanguageCode "NMTOKEN">+ <!-- a language code, as per [RFC1766] -->++<!ENTITY % Character "CDATA">+ <!-- a single character from [ISO10646] -->++<!ENTITY % Number "CDATA">+ <!-- one or more digits -->++<!ENTITY % LinkTypes "CDATA">+ <!-- space-separated list of link types -->++<!ENTITY % MediaDesc "CDATA">+ <!-- single or comma-separated list of media descriptors -->++<!ENTITY % URI "CDATA">+ <!-- a Uniform Resource Identifier, see [RFC2396] -->++<!ENTITY % UriList "CDATA">+ <!-- a space separated list of Uniform Resource Identifiers -->++<!ENTITY % Datetime "CDATA">+ <!-- date and time information. ISO date format -->++<!ENTITY % Script "CDATA">+ <!-- script expression -->++<!ENTITY % StyleSheet "CDATA">+ <!-- style sheet data -->++<!ENTITY % Text "CDATA">+ <!-- used for titles etc. -->++<!ENTITY % FrameTarget "NMTOKEN">+ <!-- render in this frame -->++<!ENTITY % Length "CDATA">+ <!-- nn for pixels or nn% for percentage length -->++<!ENTITY % MultiLength "CDATA">+ <!-- pixel, percentage, or relative -->++<!ENTITY % MultiLengths "CDATA">+ <!-- comma-separated list of MultiLength -->++<!ENTITY % Pixels "CDATA">+ <!-- integer representing length in pixels -->++<!-- these are used for image maps -->++<!ENTITY % Shape "(rect|circle|poly|default)">++<!ENTITY % Coords "CDATA">+ <!-- comma separated list of lengths -->++<!-- used for object, applet, img, input and iframe -->+<!ENTITY % ImgAlign "(top|middle|bottom|left|right)">++<!-- a color using sRGB: #RRGGBB as Hex values -->+<!ENTITY % Color "CDATA">++<!-- There are also 16 widely known color names with their sRGB values:++ Black = #000000 Green = #008000+ Silver = #C0C0C0 Lime = #00FF00+ Gray = #808080 Olive = #808000+ White = #FFFFFF Yellow = #FFFF00+ Maroon = #800000 Navy = #000080+ Red = #FF0000 Blue = #0000FF+ Purple = #800080 Teal = #008080+ Fuchsia= #FF00FF Aqua = #00FFFF+-->++<!--=================== Generic Attributes ===============================-->++<!-- core attributes common to most elements+ id document-wide unique id+ class space separated list of classes+ style associated style info+ title advisory title/amplification+-->+<!ENTITY % coreattrs+ "id ID #IMPLIED+ class CDATA #IMPLIED+ style %StyleSheet; #IMPLIED+ title %Text; #IMPLIED"+ >++<!-- internationalization attributes+ lang language code (backwards compatible)+ xml:lang language code (as per XML 1.0 spec)+ dir direction for weak/neutral text+-->+<!ENTITY % i18n+ "lang %LanguageCode; #IMPLIED+ xml:lang %LanguageCode; #IMPLIED+ dir (ltr|rtl) #IMPLIED"+ >++<!-- attributes for common UI events+ onclick a pointer button was clicked+ ondblclick a pointer button was double clicked+ onmousedown a pointer button was pressed down+ onmouseup a pointer button was released+ onmousemove a pointer was moved onto the element+ onmouseout a pointer was moved away from the element+ onkeypress a key was pressed and released+ onkeydown a key was pressed down+ onkeyup a key was released+-->+<!ENTITY % events+ "onclick %Script; #IMPLIED+ ondblclick %Script; #IMPLIED+ onmousedown %Script; #IMPLIED+ onmouseup %Script; #IMPLIED+ onmouseover %Script; #IMPLIED+ onmousemove %Script; #IMPLIED+ onmouseout %Script; #IMPLIED+ onkeypress %Script; #IMPLIED+ onkeydown %Script; #IMPLIED+ onkeyup %Script; #IMPLIED"+ >++<!-- attributes for elements that can get the focus+ accesskey accessibility key character+ tabindex position in tabbing order+ onfocus the element got the focus+ onblur the element lost the focus+-->+<!ENTITY % focus+ "accesskey %Character; #IMPLIED+ tabindex %Number; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED"+ >++<!ENTITY % attrs "%coreattrs; %i18n; %events;">++<!-- text alignment for p, div, h1-h6. The default is+ align="left" for ltr headings, "right" for rtl -->++<!ENTITY % TextAlign "align (left|center|right) #IMPLIED">++<!--=================== Text Elements ====================================-->++<!ENTITY % special+ "br | span | bdo |object | applet | img | map | iframe">++<!ENTITY % fontstyle "tt | i | b | big | small | u+ | s | strike |font | basefont">++<!ENTITY % phrase "em | strong | dfn | code | q | sub | sup |+ samp | kbd | var | cite | abbr | acronym">++<!ENTITY % inline.forms "input | select | textarea | label | button">++<!-- these can occur at block or inline level -->+<!ENTITY % misc "ins | del | script | noscript">++<!ENTITY % inline "a | %special; | %fontstyle; | %phrase; | %inline.forms;">++<!-- %Inline; covers inline or "text-level" elements -->+<!ENTITY % Inline "(#PCDATA | %inline; | %misc;)*">++<!--================== Block level elements ==============================-->++<!ENTITY % heading "h1|h2|h3|h4|h5|h6">+<!ENTITY % lists "ul | ol | dl | menu | dir">+<!ENTITY % blocktext "pre | hr | blockquote | address | center">++<!ENTITY % block+ "p | %heading; | div | %lists; | %blocktext; | isindex | fieldset | table">++<!ENTITY % Block "(%block; | form | %misc;)*">++<!-- %Flow; mixes Block and Inline and is used for list items etc. -->+<!ENTITY % Flow "(#PCDATA | %block; | form | %inline; | %misc;)*">++<!--================== Content models for exclusions =====================-->++<!-- a elements use %Inline; excluding a -->++<!ENTITY % a.content+ "(#PCDATA | %special; | %fontstyle; | %phrase; | %inline.forms; | %misc;)*">++<!-- pre uses %Inline excluding img, object, applet, big, small,+ sub, sup, font, or basefont -->++<!ENTITY % pre.content+ "(#PCDATA | a | br | span | bdo | map | tt | i | b | u | s |+ %phrase; | %inline.forms;)*">++<!-- form uses %Flow; excluding form -->++<!ENTITY % form.content "(#PCDATA | %block; | %inline; | %misc;)*">++<!-- button uses %Flow; but excludes a, form, form controls, iframe -->++<!ENTITY % button.content+ "(#PCDATA | p | %heading; | div | %lists; | %blocktext; |+ table | br | span | bdo | object | applet | img | map |+ %fontstyle; | %phrase; | %misc;)*">++<!--================ Document Structure ==================================-->++<!-- the namespace URI designates the document profile -->++<!ELEMENT html (head, frameset)>+<!ATTLIST html+ %i18n;+ xmlns %URI; #FIXED 'http://www.w3.org/1999/xhtml'+ >++<!--================ Document Head =======================================-->++<!ENTITY % head.misc "(script|style|meta|link|object|isindex)*">++<!-- content model is %head.misc; combined with a single+ title and an optional base element in any order -->++<!ELEMENT head (%head.misc;,+ ((title, %head.misc;, (base, %head.misc;)?) |+ (base, %head.misc;, (title, %head.misc;))))>++<!ATTLIST head+ %i18n;+ profile %URI; #IMPLIED+ >++<!-- The title element is not considered part of the flow of text.+ It should be displayed, for example as the page header or+ window title. Exactly one title is required per document.+ -->+<!ELEMENT title (#PCDATA)>+<!ATTLIST title %i18n;>++<!-- document base URI -->++<!ELEMENT base EMPTY>+<!ATTLIST base+ href %URI; #IMPLIED+ target %FrameTarget; #IMPLIED+ >++<!-- generic metainformation -->+<!ELEMENT meta EMPTY>+<!ATTLIST meta+ %i18n;+ http-equiv CDATA #IMPLIED+ name CDATA #IMPLIED+ content CDATA #REQUIRED+ scheme CDATA #IMPLIED+ >++<!--+ Relationship values can be used in principle:++ a) for document specific toolbars/menus when used+ with the link element in document head e.g.+ start, contents, previous, next, index, end, help+ b) to link to a separate style sheet (rel="stylesheet")+ c) to make a link to a script (rel="script")+ d) by stylesheets to control how collections of+ html nodes are rendered into printed documents+ e) to make a link to a printable version of this document+ e.g. a PostScript or PDF version (rel="alternate" media="print")+-->++<!ELEMENT link EMPTY>+<!ATTLIST link+ %attrs;+ charset %Charset; #IMPLIED+ href %URI; #IMPLIED+ hreflang %LanguageCode; #IMPLIED+ type %ContentType; #IMPLIED+ rel %LinkTypes; #IMPLIED+ rev %LinkTypes; #IMPLIED+ media %MediaDesc; #IMPLIED+ target %FrameTarget; #IMPLIED+ >++<!-- style info, which may include CDATA sections -->+<!ELEMENT style (#PCDATA)>+<!ATTLIST style+ %i18n;+ type %ContentType; #REQUIRED+ media %MediaDesc; #IMPLIED+ title %Text; #IMPLIED+ xml:space (preserve) #FIXED 'preserve'+ >++<!-- script statements, which may include CDATA sections -->+<!ELEMENT script (#PCDATA)>+<!ATTLIST script+ charset %Charset; #IMPLIED+ type %ContentType; #REQUIRED+ language CDATA #IMPLIED+ src %URI; #IMPLIED+ defer (defer) #IMPLIED+ xml:space (preserve) #FIXED 'preserve'+ >++<!-- alternate content container for non script-based rendering -->++<!ELEMENT noscript %Flow;>+<!ATTLIST noscript+ %attrs;+ >++<!--======================= Frames =======================================-->++<!-- only one noframes element permitted per document -->++<!ELEMENT frameset (frameset|frame|noframes)*>+<!ATTLIST frameset+ %coreattrs;+ rows %MultiLengths; #IMPLIED+ cols %MultiLengths; #IMPLIED+ onload %Script; #IMPLIED+ onunload %Script; #IMPLIED+ >++<!-- reserved frame names start with "_" otherwise starts with letter -->++<!-- tiled window within frameset -->++<!ELEMENT frame EMPTY>+<!ATTLIST frame+ %coreattrs;+ longdesc %URI; #IMPLIED+ name NMTOKEN #IMPLIED+ src %URI; #IMPLIED+ frameborder (1|0) "1"+ marginwidth %Pixels; #IMPLIED+ marginheight %Pixels; #IMPLIED+ noresize (noresize) #IMPLIED+ scrolling (yes|no|auto) "auto"+ >++<!-- inline subwindow -->++<!ELEMENT iframe %Flow;>+<!ATTLIST iframe+ %coreattrs;+ longdesc %URI; #IMPLIED+ name NMTOKEN #IMPLIED+ src %URI; #IMPLIED+ frameborder (1|0) "1"+ marginwidth %Pixels; #IMPLIED+ marginheight %Pixels; #IMPLIED+ scrolling (yes|no|auto) "auto"+ align %ImgAlign; #IMPLIED+ height %Length; #IMPLIED+ width %Length; #IMPLIED+ >++<!-- alternate content container for non frame-based rendering -->++<!ELEMENT noframes (body)>+<!ATTLIST noframes+ %attrs;+ >++<!--=================== Document Body ====================================-->++<!ELEMENT body %Flow;>+<!ATTLIST body+ %attrs;+ onload %Script; #IMPLIED+ onunload %Script; #IMPLIED+ background %URI; #IMPLIED+ bgcolor %Color; #IMPLIED+ text %Color; #IMPLIED+ link %Color; #IMPLIED+ vlink %Color; #IMPLIED+ alink %Color; #IMPLIED+ >++<!ELEMENT div %Flow;> <!-- generic language/style container -->+<!ATTLIST div+ %attrs;+ %TextAlign;+ >++<!--=================== Paragraphs =======================================-->++<!ELEMENT p %Inline;>+<!ATTLIST p+ %attrs;+ %TextAlign;+ >++<!--=================== Headings =========================================-->++<!--+ There are six levels of headings from h1 (the most important)+ to h6 (the least important).+-->++<!ELEMENT h1 %Inline;>+<!ATTLIST h1+ %attrs;+ %TextAlign;+ >++<!ELEMENT h2 %Inline;>+<!ATTLIST h2+ %attrs;+ %TextAlign;+ >++<!ELEMENT h3 %Inline;>+<!ATTLIST h3+ %attrs;+ %TextAlign;+ >++<!ELEMENT h4 %Inline;>+<!ATTLIST h4+ %attrs;+ %TextAlign;+ >++<!ELEMENT h5 %Inline;>+<!ATTLIST h5+ %attrs;+ %TextAlign;+ >++<!ELEMENT h6 %Inline;>+<!ATTLIST h6+ %attrs;+ %TextAlign;+ >++<!--=================== Lists ============================================-->++<!-- Unordered list bullet styles -->++<!ENTITY % ULStyle "(disc|square|circle)">++<!-- Unordered list -->++<!ELEMENT ul (li)+>+<!ATTLIST ul+ %attrs;+ type %ULStyle; #IMPLIED+ compact (compact) #IMPLIED+ >++<!-- Ordered list numbering style++ 1 arabic numbers 1, 2, 3, ...+ a lower alpha a, b, c, ...+ A upper alpha A, B, C, ...+ i lower roman i, ii, iii, ...+ I upper roman I, II, III, ...++ The style is applied to the sequence number which by default+ is reset to 1 for the first list item in an ordered list.+-->+<!ENTITY % OLStyle "CDATA">++<!-- Ordered (numbered) list -->++<!ELEMENT ol (li)+>+<!ATTLIST ol+ %attrs;+ type %OLStyle; #IMPLIED+ compact (compact) #IMPLIED+ start %Number; #IMPLIED+ >++<!-- single column list (DEPRECATED) --> +<!ELEMENT menu (li)+>+<!ATTLIST menu+ %attrs;+ compact (compact) #IMPLIED+ >++<!-- multiple column list (DEPRECATED) --> +<!ELEMENT dir (li)+>+<!ATTLIST dir+ %attrs;+ compact (compact) #IMPLIED+ >++<!-- LIStyle is constrained to: "(%ULStyle;|%OLStyle;)" -->+<!ENTITY % LIStyle "CDATA">++<!-- list item -->++<!ELEMENT li %Flow;>+<!ATTLIST li+ %attrs;+ type %LIStyle; #IMPLIED+ value %Number; #IMPLIED+ >++<!-- definition lists - dt for term, dd for its definition -->++<!ELEMENT dl (dt|dd)+>+<!ATTLIST dl+ %attrs;+ compact (compact) #IMPLIED+ >++<!ELEMENT dt %Inline;>+<!ATTLIST dt+ %attrs;+ >++<!ELEMENT dd %Flow;>+<!ATTLIST dd+ %attrs;+ >++<!--=================== Address ==========================================-->++<!-- information on author -->++<!ELEMENT address %Inline;>+<!ATTLIST address+ %attrs;+ >++<!--=================== Horizontal Rule ==================================-->++<!ELEMENT hr EMPTY>+<!ATTLIST hr+ %attrs;+ align (left|center|right) #IMPLIED+ noshade (noshade) #IMPLIED+ size %Pixels; #IMPLIED+ width %Length; #IMPLIED+ >++<!--=================== Preformatted Text ================================-->++<!-- content is %Inline; excluding + "img|object|applet|big|small|sub|sup|font|basefont" -->++<!ELEMENT pre %pre.content;>+<!ATTLIST pre+ %attrs;+ width %Number; #IMPLIED+ xml:space (preserve) #FIXED 'preserve'+ >++<!--=================== Block-like Quotes ================================-->++<!ELEMENT blockquote %Flow;>+<!ATTLIST blockquote+ %attrs;+ cite %URI; #IMPLIED+ >++<!--=================== Text alignment ===================================-->++<!-- center content -->+<!ELEMENT center %Flow;>+<!ATTLIST center+ %attrs;+ >++<!--=================== Inserted/Deleted Text ============================-->+++<!--+ ins/del are allowed in block and inline content, but its+ inappropriate to include block content within an ins element+ occurring in inline content.+-->+<!ELEMENT ins %Flow;>+<!ATTLIST ins+ %attrs;+ cite %URI; #IMPLIED+ datetime %Datetime; #IMPLIED+ >++<!ELEMENT del %Flow;>+<!ATTLIST del+ %attrs;+ cite %URI; #IMPLIED+ datetime %Datetime; #IMPLIED+ >++<!--================== The Anchor Element ================================-->++<!-- content is %Inline; except that anchors shouldn't be nested -->++<!ELEMENT a %a.content;>+<!ATTLIST a+ %attrs;+ charset %Charset; #IMPLIED+ type %ContentType; #IMPLIED+ name NMTOKEN #IMPLIED+ href %URI; #IMPLIED+ hreflang %LanguageCode; #IMPLIED+ rel %LinkTypes; #IMPLIED+ rev %LinkTypes; #IMPLIED+ accesskey %Character; #IMPLIED+ shape %Shape; "rect"+ coords %Coords; #IMPLIED+ tabindex %Number; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED+ target %FrameTarget; #IMPLIED+ >++<!--===================== Inline Elements ================================-->++<!ELEMENT span %Inline;> <!-- generic language/style container -->+<!ATTLIST span+ %attrs;+ >++<!ELEMENT bdo %Inline;> <!-- I18N BiDi over-ride -->+<!ATTLIST bdo+ %coreattrs;+ %events;+ lang %LanguageCode; #IMPLIED+ xml:lang %LanguageCode; #IMPLIED+ dir (ltr|rtl) #REQUIRED+ >++<!ELEMENT br EMPTY> <!-- forced line break -->+<!ATTLIST br+ %coreattrs;+ clear (left|all|right|none) "none"+ >++<!ELEMENT em %Inline;> <!-- emphasis -->+<!ATTLIST em %attrs;>++<!ELEMENT strong %Inline;> <!-- strong emphasis -->+<!ATTLIST strong %attrs;>++<!ELEMENT dfn %Inline;> <!-- definitional -->+<!ATTLIST dfn %attrs;>++<!ELEMENT code %Inline;> <!-- program code -->+<!ATTLIST code %attrs;>++<!ELEMENT samp %Inline;> <!-- sample -->+<!ATTLIST samp %attrs;>++<!ELEMENT kbd %Inline;> <!-- something user would type -->+<!ATTLIST kbd %attrs;>++<!ELEMENT var %Inline;> <!-- variable -->+<!ATTLIST var %attrs;>++<!ELEMENT cite %Inline;> <!-- citation -->+<!ATTLIST cite %attrs;>++<!ELEMENT abbr %Inline;> <!-- abbreviation -->+<!ATTLIST abbr %attrs;>++<!ELEMENT acronym %Inline;> <!-- acronym -->+<!ATTLIST acronym %attrs;>++<!ELEMENT q %Inline;> <!-- inlined quote -->+<!ATTLIST q+ %attrs;+ cite %URI; #IMPLIED+ >++<!ELEMENT sub %Inline;> <!-- subscript -->+<!ATTLIST sub %attrs;>++<!ELEMENT sup %Inline;> <!-- superscript -->+<!ATTLIST sup %attrs;>++<!ELEMENT tt %Inline;> <!-- fixed pitch font -->+<!ATTLIST tt %attrs;>++<!ELEMENT i %Inline;> <!-- italic font -->+<!ATTLIST i %attrs;>++<!ELEMENT b %Inline;> <!-- bold font -->+<!ATTLIST b %attrs;>++<!ELEMENT big %Inline;> <!-- bigger font -->+<!ATTLIST big %attrs;>++<!ELEMENT small %Inline;> <!-- smaller font -->+<!ATTLIST small %attrs;>++<!ELEMENT u %Inline;> <!-- underline -->+<!ATTLIST u %attrs;>++<!ELEMENT s %Inline;> <!-- strike-through -->+<!ATTLIST s %attrs;>++<!ELEMENT strike %Inline;> <!-- strike-through -->+<!ATTLIST strike %attrs;>++<!ELEMENT basefont EMPTY> <!-- base font size -->+<!ATTLIST basefont+ id ID #IMPLIED+ size CDATA #REQUIRED+ color %Color; #IMPLIED+ face CDATA #IMPLIED+ >++<!ELEMENT font %Inline;> <!-- local change to font -->+<!ATTLIST font+ %coreattrs;+ %i18n;+ size CDATA #IMPLIED+ color %Color; #IMPLIED+ face CDATA #IMPLIED+ >++<!--==================== Object ======================================-->+<!--+ object is used to embed objects as part of HTML pages.+ param elements should precede other content. Parameters+ can also be expressed as attribute/value pairs on the+ object element itself when brevity is desired.+-->++<!ELEMENT object (#PCDATA | param | %block; | form |%inline; | %misc;)*>+<!ATTLIST object+ %attrs;+ declare (declare) #IMPLIED+ classid %URI; #IMPLIED+ codebase %URI; #IMPLIED+ data %URI; #IMPLIED+ type %ContentType; #IMPLIED+ codetype %ContentType; #IMPLIED+ archive %UriList; #IMPLIED+ standby %Text; #IMPLIED+ height %Length; #IMPLIED+ width %Length; #IMPLIED+ usemap %URI; #IMPLIED+ name NMTOKEN #IMPLIED+ tabindex %Number; #IMPLIED+ align %ImgAlign; #IMPLIED+ border %Pixels; #IMPLIED+ hspace %Pixels; #IMPLIED+ vspace %Pixels; #IMPLIED+ >++<!--+ param is used to supply a named property value.+ In XML it would seem natural to follow RDF and support an+ abbreviated syntax where the param elements are replaced+ by attribute value pairs on the object start tag.+-->+<!ELEMENT param EMPTY>+<!ATTLIST param+ id ID #IMPLIED+ name CDATA #REQUIRED+ value CDATA #IMPLIED+ valuetype (data|ref|object) "data"+ type %ContentType; #IMPLIED+ >++<!--=================== Java applet ==================================-->+<!--+ One of code or object attributes must be present.+ Place param elements before other content.+-->+<!ELEMENT applet (#PCDATA | param | %block; | form | %inline; | %misc;)*>+<!ATTLIST applet+ %coreattrs;+ codebase %URI; #IMPLIED+ archive CDATA #IMPLIED+ code CDATA #IMPLIED+ object CDATA #IMPLIED+ alt %Text; #IMPLIED+ name NMTOKEN #IMPLIED+ width %Length; #REQUIRED+ height %Length; #REQUIRED+ align %ImgAlign; #IMPLIED+ hspace %Pixels; #IMPLIED+ vspace %Pixels; #IMPLIED+ >++<!--=================== Images ===========================================-->++<!--+ To avoid accessibility problems for people who aren't+ able to see the image, you should provide a text+ description using the alt and longdesc attributes.+ In addition, avoid the use of server-side image maps.+-->++<!ELEMENT img EMPTY>+<!ATTLIST img+ %attrs;+ src %URI; #REQUIRED+ alt %Text; #REQUIRED+ name NMTOKEN #IMPLIED+ longdesc %URI; #IMPLIED+ height %Length; #IMPLIED+ width %Length; #IMPLIED+ usemap %URI; #IMPLIED+ ismap (ismap) #IMPLIED+ align %ImgAlign; #IMPLIED+ border %Pixels; #IMPLIED+ hspace %Pixels; #IMPLIED+ vspace %Pixels; #IMPLIED+ >++<!-- usemap points to a map element which may be in this document+ or an external document, although the latter is not widely supported -->++<!--================== Client-side image maps ============================-->++<!-- These can be placed in the same document or grouped in a+ separate document although this isn't yet widely supported -->++<!ELEMENT map ((%block; | form | %misc;)+ | area+)>+<!ATTLIST map+ %i18n;+ %events;+ id ID #REQUIRED+ class CDATA #IMPLIED+ style %StyleSheet; #IMPLIED+ title %Text; #IMPLIED+ name NMTOKEN #IMPLIED+ >++<!ELEMENT area EMPTY>+<!ATTLIST area+ %attrs;+ shape %Shape; "rect"+ coords %Coords; #IMPLIED+ href %URI; #IMPLIED+ nohref (nohref) #IMPLIED+ alt %Text; #REQUIRED+ tabindex %Number; #IMPLIED+ accesskey %Character; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED+ target %FrameTarget; #IMPLIED+ >++<!--================ Forms ===============================================-->++<!ELEMENT form %form.content;> <!-- forms shouldn't be nested -->++<!ATTLIST form+ %attrs;+ action %URI; #REQUIRED+ method (get|post) "get"+ name NMTOKEN #IMPLIED+ enctype %ContentType; "application/x-www-form-urlencoded"+ onsubmit %Script; #IMPLIED+ onreset %Script; #IMPLIED+ accept %ContentTypes; #IMPLIED+ accept-charset %Charsets; #IMPLIED+ target %FrameTarget; #IMPLIED+ >++<!--+ Each label must not contain more than ONE field+ Label elements shouldn't be nested.+-->+<!ELEMENT label %Inline;>+<!ATTLIST label+ %attrs;+ for IDREF #IMPLIED+ accesskey %Character; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED+ >++<!ENTITY % InputType+ "(text | password | checkbox |+ radio | submit | reset |+ file | hidden | image | button)"+ >++<!-- the name attribute is required for all but submit & reset -->++<!ELEMENT input EMPTY> <!-- form control -->+<!ATTLIST input+ %attrs;+ type %InputType; "text"+ name CDATA #IMPLIED+ value CDATA #IMPLIED+ checked (checked) #IMPLIED+ disabled (disabled) #IMPLIED+ readonly (readonly) #IMPLIED+ size CDATA #IMPLIED+ maxlength %Number; #IMPLIED+ src %URI; #IMPLIED+ alt CDATA #IMPLIED+ usemap %URI; #IMPLIED+ tabindex %Number; #IMPLIED+ accesskey %Character; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED+ onselect %Script; #IMPLIED+ onchange %Script; #IMPLIED+ accept %ContentTypes; #IMPLIED+ align %ImgAlign; #IMPLIED+ >++<!ELEMENT select (optgroup|option)+> <!-- option selector -->+<!ATTLIST select+ %attrs;+ name CDATA #IMPLIED+ size %Number; #IMPLIED+ multiple (multiple) #IMPLIED+ disabled (disabled) #IMPLIED+ tabindex %Number; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED+ onchange %Script; #IMPLIED+ >++<!ELEMENT optgroup (option)+> <!-- option group -->+<!ATTLIST optgroup+ %attrs;+ disabled (disabled) #IMPLIED+ label %Text; #REQUIRED+ >++<!ELEMENT option (#PCDATA)> <!-- selectable choice -->+<!ATTLIST option+ %attrs;+ selected (selected) #IMPLIED+ disabled (disabled) #IMPLIED+ label %Text; #IMPLIED+ value CDATA #IMPLIED+ >++<!ELEMENT textarea (#PCDATA)> <!-- multi-line text field -->+<!ATTLIST textarea+ %attrs;+ name CDATA #IMPLIED+ rows %Number; #REQUIRED+ cols %Number; #REQUIRED+ disabled (disabled) #IMPLIED+ readonly (readonly) #IMPLIED+ tabindex %Number; #IMPLIED+ accesskey %Character; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED+ onselect %Script; #IMPLIED+ onchange %Script; #IMPLIED+ >++<!--+ The fieldset element is used to group form fields.+ Only one legend element should occur in the content+ and if present should only be preceded by whitespace.+-->+<!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*>+<!ATTLIST fieldset+ %attrs;+ >++<!ENTITY % LAlign "(top|bottom|left|right)">++<!ELEMENT legend %Inline;> <!-- fieldset label -->+<!ATTLIST legend+ %attrs;+ accesskey %Character; #IMPLIED+ align %LAlign; #IMPLIED+ >++<!--+ Content is %Flow; excluding a, form, form controls, iframe+--> +<!ELEMENT button %button.content;> <!-- push button -->+<!ATTLIST button+ %attrs;+ name CDATA #IMPLIED+ value CDATA #IMPLIED+ type (button|submit|reset) "submit"+ disabled (disabled) #IMPLIED+ tabindex %Number; #IMPLIED+ accesskey %Character; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED+ >++<!-- single-line text input control (DEPRECATED) -->+<!ELEMENT isindex EMPTY>+<!ATTLIST isindex+ %coreattrs;+ %i18n;+ prompt %Text; #IMPLIED+ >++<!--======================= Tables =======================================-->++<!-- Derived from IETF HTML table standard, see [RFC1942] -->++<!--+ The border attribute sets the thickness of the frame around the+ table. The default units are screen pixels.++ The frame attribute specifies which parts of the frame around+ the table should be rendered. The values are not the same as+ CALS to avoid a name clash with the valign attribute.+-->+<!ENTITY % TFrame "(void|above|below|hsides|lhs|rhs|vsides|box|border)">++<!--+ The rules attribute defines which rules to draw between cells:++ If rules is absent then assume:+ "none" if border is absent or border="0" otherwise "all"+-->++<!ENTITY % TRules "(none | groups | rows | cols | all)">+ +<!-- horizontal placement of table relative to document -->+<!ENTITY % TAlign "(left|center|right)">++<!-- horizontal alignment attributes for cell contents++ char alignment char, e.g. char=":"+ charoff offset for alignment char+-->+<!ENTITY % cellhalign+ "align (left|center|right|justify|char) #IMPLIED+ char %Character; #IMPLIED+ charoff %Length; #IMPLIED"+ >++<!-- vertical alignment attributes for cell contents -->+<!ENTITY % cellvalign+ "valign (top|middle|bottom|baseline) #IMPLIED"+ >++<!ELEMENT table+ (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))>+<!ELEMENT caption %Inline;>+<!ELEMENT thead (tr)+>+<!ELEMENT tfoot (tr)+>+<!ELEMENT tbody (tr)+>+<!ELEMENT colgroup (col)*>+<!ELEMENT col EMPTY>+<!ELEMENT tr (th|td)+>+<!ELEMENT th %Flow;>+<!ELEMENT td %Flow;>++<!ATTLIST table+ %attrs;+ summary %Text; #IMPLIED+ width %Length; #IMPLIED+ border %Pixels; #IMPLIED+ frame %TFrame; #IMPLIED+ rules %TRules; #IMPLIED+ cellspacing %Length; #IMPLIED+ cellpadding %Length; #IMPLIED+ align %TAlign; #IMPLIED+ bgcolor %Color; #IMPLIED+ >++<!ENTITY % CAlign "(top|bottom|left|right)">++<!ATTLIST caption+ %attrs;+ align %CAlign; #IMPLIED+ >++<!--+colgroup groups a set of col elements. It allows you to group+several semantically related columns together.+-->+<!ATTLIST colgroup+ %attrs;+ span %Number; "1"+ width %MultiLength; #IMPLIED+ %cellhalign;+ %cellvalign;+ >++<!--+ col elements define the alignment properties for cells in+ one or more columns.++ The width attribute specifies the width of the columns, e.g.++ width=64 width in screen pixels+ width=0.5* relative width of 0.5++ The span attribute causes the attributes of one+ col element to apply to more than one column.+-->+<!ATTLIST col+ %attrs;+ span %Number; "1"+ width %MultiLength; #IMPLIED+ %cellhalign;+ %cellvalign;+ >++<!--+ Use thead to duplicate headers when breaking table+ across page boundaries, or for static headers when+ tbody sections are rendered in scrolling panel.++ Use tfoot to duplicate footers when breaking table+ across page boundaries, or for static footers when+ tbody sections are rendered in scrolling panel.++ Use multiple tbody sections when rules are needed+ between groups of table rows.+-->+<!ATTLIST thead+ %attrs;+ %cellhalign;+ %cellvalign;+ >++<!ATTLIST tfoot+ %attrs;+ %cellhalign;+ %cellvalign;+ >++<!ATTLIST tbody+ %attrs;+ %cellhalign;+ %cellvalign;+ >++<!ATTLIST tr+ %attrs;+ %cellhalign;+ %cellvalign;+ bgcolor %Color; #IMPLIED+ >++<!-- Scope is simpler than headers attribute for common tables -->+<!ENTITY % Scope "(row|col|rowgroup|colgroup)">++<!-- th is for headers, td for data and for cells acting as both -->++<!ATTLIST th+ %attrs;+ abbr %Text; #IMPLIED+ axis CDATA #IMPLIED+ headers IDREFS #IMPLIED+ scope %Scope; #IMPLIED+ rowspan %Number; "1"+ colspan %Number; "1"+ %cellhalign;+ %cellvalign;+ nowrap (nowrap) #IMPLIED+ bgcolor %Color; #IMPLIED+ width %Pixels; #IMPLIED+ height %Pixels; #IMPLIED+ >++<!ATTLIST td+ %attrs;+ abbr %Text; #IMPLIED+ axis CDATA #IMPLIED+ headers IDREFS #IMPLIED+ scope %Scope; #IMPLIED+ rowspan %Number; "1"+ colspan %Number; "1"+ %cellhalign;+ %cellvalign;+ nowrap (nowrap) #IMPLIED+ bgcolor %Color; #IMPLIED+ width %Pixels; #IMPLIED+ height %Pixels; #IMPLIED+ >+
+ examples/hxpath/xhtml/xhtml1-strict.dtd view
@@ -0,0 +1,988 @@+<!--+ Extensible HTML version 1.0 Strict DTD++ This is the same as HTML 4.0 Strict except for+ changes due to the differences between XML and SGML.++ Namespace = http://www.w3.org/1999/xhtml++ For further information, see: http://www.w3.org/TR/xhtml1++ Copyright (c) 1998-2000 W3C (MIT, INRIA, Keio),+ All Rights Reserved. ++ This DTD module is identified by the PUBLIC and SYSTEM identifiers:++ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"+ SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"++ $Revision: 1.1 $+ $Date: 2002/10/01 13:47:08 $++-->++<!--================ Character mnemonic entities =========================-->++<!ENTITY % HTMLlat1 PUBLIC+ "-//W3C//ENTITIES Latin 1 for XHTML//EN"+ "xhtml-lat1.ent">+%HTMLlat1;++<!ENTITY % HTMLsymbol PUBLIC+ "-//W3C//ENTITIES Symbols for XHTML//EN"+ "xhtml-symbol.ent">+%HTMLsymbol;++<!ENTITY % HTMLspecial PUBLIC+ "-//W3C//ENTITIES Special for XHTML//EN"+ "xhtml-special.ent">+%HTMLspecial;++<!--================== Imported Names ====================================-->++<!ENTITY % ContentType "CDATA">+ <!-- media type, as per [RFC2045] -->++<!ENTITY % ContentTypes "CDATA">+ <!-- comma-separated list of media types, as per [RFC2045] -->++<!ENTITY % Charset "CDATA">+ <!-- a character encoding, as per [RFC2045] -->++<!ENTITY % Charsets "CDATA">+ <!-- a space separated list of character encodings, as per [RFC2045] -->++<!ENTITY % LanguageCode "NMTOKEN">+ <!-- a language code, as per [RFC1766] -->++<!ENTITY % Character "CDATA">+ <!-- a single character from [ISO10646] -->++<!ENTITY % Number "CDATA">+ <!-- one or more digits -->++<!ENTITY % LinkTypes "CDATA">+ <!-- space-separated list of link types -->++<!ENTITY % MediaDesc "CDATA">+ <!-- single or comma-separated list of media descriptors -->++<!ENTITY % URI "CDATA">+ <!-- a Uniform Resource Identifier, see [RFC2396] -->++<!ENTITY % UriList "CDATA">+ <!-- a space separated list of Uniform Resource Identifiers -->++<!ENTITY % Datetime "CDATA">+ <!-- date and time information. ISO date format -->++<!ENTITY % Script "CDATA">+ <!-- script expression -->++<!ENTITY % StyleSheet "CDATA">+ <!-- style sheet data -->++<!ENTITY % Text "CDATA">+ <!-- used for titles etc. -->++<!ENTITY % FrameTarget "NMTOKEN">+ <!-- render in this frame -->++<!ENTITY % Length "CDATA">+ <!-- nn for pixels or nn% for percentage length -->++<!ENTITY % MultiLength "CDATA">+ <!-- pixel, percentage, or relative -->++<!ENTITY % MultiLengths "CDATA">+ <!-- comma-separated list of MultiLength -->++<!ENTITY % Pixels "CDATA">+ <!-- integer representing length in pixels -->++<!-- these are used for image maps -->++<!ENTITY % Shape "(rect|circle|poly|default)">++<!ENTITY % Coords "CDATA">+ <!-- comma separated list of lengths -->++<!--=================== Generic Attributes ===============================-->++<!-- core attributes common to most elements+ id document-wide unique id+ class space separated list of classes+ style associated style info+ title advisory title/amplification+-->+<!ENTITY % coreattrs+ "id ID #IMPLIED+ class CDATA #IMPLIED+ style %StyleSheet; #IMPLIED+ title %Text; #IMPLIED"+ >++<!-- internationalization attributes+ lang language code (backwards compatible)+ xml:lang language code (as per XML 1.0 spec)+ dir direction for weak/neutral text+-->+<!ENTITY % i18n+ "lang %LanguageCode; #IMPLIED+ xml:lang %LanguageCode; #IMPLIED+ dir (ltr|rtl) #IMPLIED"+ >++<!-- attributes for common UI events+ onclick a pointer button was clicked+ ondblclick a pointer button was double clicked+ onmousedown a pointer button was pressed down+ onmouseup a pointer button was released+ onmousemove a pointer was moved onto the element+ onmouseout a pointer was moved away from the element+ onkeypress a key was pressed and released+ onkeydown a key was pressed down+ onkeyup a key was released+-->+<!ENTITY % events+ "onclick %Script; #IMPLIED+ ondblclick %Script; #IMPLIED+ onmousedown %Script; #IMPLIED+ onmouseup %Script; #IMPLIED+ onmouseover %Script; #IMPLIED+ onmousemove %Script; #IMPLIED+ onmouseout %Script; #IMPLIED+ onkeypress %Script; #IMPLIED+ onkeydown %Script; #IMPLIED+ onkeyup %Script; #IMPLIED"+ >++<!-- attributes for elements that can get the focus+ accesskey accessibility key character+ tabindex position in tabbing order+ onfocus the element got the focus+ onblur the element lost the focus+-->+<!ENTITY % focus+ "accesskey %Character; #IMPLIED+ tabindex %Number; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED"+ >++<!ENTITY % attrs "%coreattrs; %i18n; %events;">++<!--=================== Text Elements ====================================-->++<!ENTITY % special+ "br | span | bdo | object | img | map">++<!ENTITY % fontstyle "tt | i | b | big | small">++<!ENTITY % phrase "em | strong | dfn | code | q | sub | sup |+ samp | kbd | var | cite | abbr | acronym">++<!ENTITY % inline.forms "input | select | textarea | label | button">++<!-- these can occur at block or inline level -->+<!ENTITY % misc "ins | del | script | noscript">++<!ENTITY % inline "a | %special; | %fontstyle; | %phrase; | %inline.forms;">++<!-- %Inline; covers inline or "text-level" elements -->+<!ENTITY % Inline "(#PCDATA | %inline; | %misc;)*">++<!--================== Block level elements ==============================-->++<!ENTITY % heading "h1|h2|h3|h4|h5|h6">+<!ENTITY % lists "ul | ol | dl">+<!ENTITY % blocktext "pre | hr | blockquote | address">++<!ENTITY % block+ "p | %heading; | div | %lists; | %blocktext; | fieldset | table">++<!ENTITY % Block "(%block; | form | %misc;)*">++<!-- %Flow; mixes Block and Inline and is used for list items etc. -->+<!ENTITY % Flow "(#PCDATA | %block; | form | %inline; | %misc;)*">++<!--================== Content models for exclusions =====================-->++<!-- a elements use %Inline; excluding a -->++<!ENTITY % a.content+ "(#PCDATA | %special; | %fontstyle; | %phrase; | %inline.forms; | %misc;)*">++<!-- pre uses %Inline excluding img, object, big, small, sup or sup -->++<!ENTITY % pre.content+ "(#PCDATA | a | br | span | bdo | map | tt | i | b |+ %phrase; | %inline.forms;)*">++<!-- form uses %Block; excluding form -->++<!ENTITY % form.content "(%block; | %misc;)*">++<!-- button uses %Flow; but excludes a, form and form controls -->++<!ENTITY % button.content+ "(#PCDATA | p | %heading; | div | %lists; | %blocktext; |+ table | %special; | %fontstyle; | %phrase; | %misc;)*">++<!--================ Document Structure ==================================-->++<!-- the namespace URI designates the document profile -->++<!ELEMENT html (head, body)>+<!ATTLIST html+ %i18n;+ xmlns %URI; #FIXED 'http://www.w3.org/1999/xhtml'+ >++<!--================ Document Head =======================================-->++<!ENTITY % head.misc "(script|style|meta|link|object)*">++<!-- content model is %head.misc; combined with a single+ title and an optional base element in any order -->++<!ELEMENT head (%head.misc;,+ ((title, %head.misc;, (base, %head.misc;)?) |+ (base, %head.misc;, (title, %head.misc;))))>++<!ATTLIST head+ %i18n;+ profile %URI; #IMPLIED+ >++<!-- The title element is not considered part of the flow of text.+ It should be displayed, for example as the page header or+ window title. Exactly one title is required per document.+ -->+<!ELEMENT title (#PCDATA)>+<!ATTLIST title %i18n;>++<!-- document base URI -->++<!ELEMENT base EMPTY>+<!ATTLIST base+ href %URI; #IMPLIED+ >++<!-- generic metainformation -->+<!ELEMENT meta EMPTY>+<!ATTLIST meta+ %i18n;+ http-equiv CDATA #IMPLIED+ name CDATA #IMPLIED+ content CDATA #REQUIRED+ scheme CDATA #IMPLIED+ >++<!--+ Relationship values can be used in principle:++ a) for document specific toolbars/menus when used+ with the link element in document head e.g.+ start, contents, previous, next, index, end, help+ b) to link to a separate style sheet (rel="stylesheet")+ c) to make a link to a script (rel="script")+ d) by stylesheets to control how collections of+ html nodes are rendered into printed documents+ e) to make a link to a printable version of this document+ e.g. a PostScript or PDF version (rel="alternate" media="print")+-->++<!ELEMENT link EMPTY>+<!ATTLIST link+ %attrs;+ charset %Charset; #IMPLIED+ href %URI; #IMPLIED+ hreflang %LanguageCode; #IMPLIED+ type %ContentType; #IMPLIED+ rel %LinkTypes; #IMPLIED+ rev %LinkTypes; #IMPLIED+ media %MediaDesc; #IMPLIED+ >++<!-- style info, which may include CDATA sections -->+<!ELEMENT style (#PCDATA)>+<!ATTLIST style+ %i18n;+ type %ContentType; #REQUIRED+ media %MediaDesc; #IMPLIED+ title %Text; #IMPLIED+ xml:space (preserve) #FIXED 'preserve'+ >++<!-- script statements, which may include CDATA sections -->+<!ELEMENT script (#PCDATA)>+<!ATTLIST script+ charset %Charset; #IMPLIED+ type %ContentType; #REQUIRED+ src %URI; #IMPLIED+ defer (defer) #IMPLIED+ xml:space (preserve) #FIXED 'preserve'+ >++<!-- alternate content container for non script-based rendering -->++<!ELEMENT noscript %Block;>+<!ATTLIST noscript+ %attrs;+ >++<!--=================== Document Body ====================================-->++<!ELEMENT body %Block;>+<!ATTLIST body+ %attrs;+ onload %Script; #IMPLIED+ onunload %Script; #IMPLIED+ >++<!ELEMENT div %Flow;> <!-- generic language/style container -->+<!ATTLIST div+ %attrs;+ >++<!--=================== Paragraphs =======================================-->++<!ELEMENT p %Inline;>+<!ATTLIST p+ %attrs;+ >++<!--=================== Headings =========================================-->++<!--+ There are six levels of headings from h1 (the most important)+ to h6 (the least important).+-->++<!ELEMENT h1 %Inline;>+<!ATTLIST h1+ %attrs;+ >++<!ELEMENT h2 %Inline;>+<!ATTLIST h2+ %attrs;+ >++<!ELEMENT h3 %Inline;>+<!ATTLIST h3+ %attrs;+ >++<!ELEMENT h4 %Inline;>+<!ATTLIST h4+ %attrs;+ >++<!ELEMENT h5 %Inline;>+<!ATTLIST h5+ %attrs;+ >++<!ELEMENT h6 %Inline;>+<!ATTLIST h6+ %attrs;+ >++<!--=================== Lists ============================================-->++<!-- Unordered list -->++<!ELEMENT ul (li)+>+<!ATTLIST ul+ %attrs;+ >++<!-- Ordered (numbered) list -->++<!ELEMENT ol (li)+>+<!ATTLIST ol+ %attrs;+ >++<!-- list item -->++<!ELEMENT li %Flow;>+<!ATTLIST li+ %attrs;+ >++<!-- definition lists - dt for term, dd for its definition -->++<!ELEMENT dl (dt|dd)+>+<!ATTLIST dl+ %attrs;+ >++<!ELEMENT dt %Inline;>+<!ATTLIST dt+ %attrs;+ >++<!ELEMENT dd %Flow;>+<!ATTLIST dd+ %attrs;+ >++<!--=================== Address ==========================================-->++<!-- information on author -->++<!ELEMENT address %Inline;>+<!ATTLIST address+ %attrs;+ >++<!--=================== Horizontal Rule ==================================-->++<!ELEMENT hr EMPTY>+<!ATTLIST hr+ %attrs;+ >++<!--=================== Preformatted Text ================================-->++<!-- content is %Inline; excluding "img|object|big|small|sub|sup" -->++<!ELEMENT pre %pre.content;>+<!ATTLIST pre+ %attrs;+ xml:space (preserve) #FIXED 'preserve'+ >++<!--=================== Block-like Quotes ================================-->++<!ELEMENT blockquote %Block;>+<!ATTLIST blockquote+ %attrs;+ cite %URI; #IMPLIED+ >++<!--=================== Inserted/Deleted Text ============================-->++<!--+ ins/del are allowed in block and inline content, but its+ inappropriate to include block content within an ins element+ occurring in inline content.+-->+<!ELEMENT ins %Flow;>+<!ATTLIST ins+ %attrs;+ cite %URI; #IMPLIED+ datetime %Datetime; #IMPLIED+ >++<!ELEMENT del %Flow;>+<!ATTLIST del+ %attrs;+ cite %URI; #IMPLIED+ datetime %Datetime; #IMPLIED+ >++<!--================== The Anchor Element ================================-->++<!-- content is %Inline; except that anchors shouldn't be nested -->++<!ELEMENT a %a.content;>+<!ATTLIST a+ %attrs;+ charset %Charset; #IMPLIED+ type %ContentType; #IMPLIED+ name NMTOKEN #IMPLIED+ href %URI; #IMPLIED+ hreflang %LanguageCode; #IMPLIED+ rel %LinkTypes; #IMPLIED+ rev %LinkTypes; #IMPLIED+ accesskey %Character; #IMPLIED+ shape %Shape; "rect"+ coords %Coords; #IMPLIED+ tabindex %Number; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED+ >++<!--===================== Inline Elements ================================-->++<!ELEMENT span %Inline;> <!-- generic language/style container -->+<!ATTLIST span+ %attrs;+ >++<!ELEMENT bdo %Inline;> <!-- I18N BiDi over-ride -->+<!ATTLIST bdo+ %coreattrs;+ %events;+ lang %LanguageCode; #IMPLIED+ xml:lang %LanguageCode; #IMPLIED+ dir (ltr|rtl) #REQUIRED+ >++<!ELEMENT br EMPTY> <!-- forced line break -->+<!ATTLIST br+ %coreattrs;+ >++<!ELEMENT em %Inline;> <!-- emphasis -->+<!ATTLIST em %attrs;>++<!ELEMENT strong %Inline;> <!-- strong emphasis -->+<!ATTLIST strong %attrs;>++<!ELEMENT dfn %Inline;> <!-- definitional -->+<!ATTLIST dfn %attrs;>++<!ELEMENT code %Inline;> <!-- program code -->+<!ATTLIST code %attrs;>++<!ELEMENT samp %Inline;> <!-- sample -->+<!ATTLIST samp %attrs;>++<!ELEMENT kbd %Inline;> <!-- something user would type -->+<!ATTLIST kbd %attrs;>++<!ELEMENT var %Inline;> <!-- variable -->+<!ATTLIST var %attrs;>++<!ELEMENT cite %Inline;> <!-- citation -->+<!ATTLIST cite %attrs;>++<!ELEMENT abbr %Inline;> <!-- abbreviation -->+<!ATTLIST abbr %attrs;>++<!ELEMENT acronym %Inline;> <!-- acronym -->+<!ATTLIST acronym %attrs;>++<!ELEMENT q %Inline;> <!-- inlined quote -->+<!ATTLIST q+ %attrs;+ cite %URI; #IMPLIED+ >++<!ELEMENT sub %Inline;> <!-- subscript -->+<!ATTLIST sub %attrs;>++<!ELEMENT sup %Inline;> <!-- superscript -->+<!ATTLIST sup %attrs;>++<!ELEMENT tt %Inline;> <!-- fixed pitch font -->+<!ATTLIST tt %attrs;>++<!ELEMENT i %Inline;> <!-- italic font -->+<!ATTLIST i %attrs;>++<!ELEMENT b %Inline;> <!-- bold font -->+<!ATTLIST b %attrs;>++<!ELEMENT big %Inline;> <!-- bigger font -->+<!ATTLIST big %attrs;>++<!ELEMENT small %Inline;> <!-- smaller font -->+<!ATTLIST small %attrs;>++<!--==================== Object ======================================-->+<!--+ object is used to embed objects as part of HTML pages.+ param elements should precede other content. Parameters+ can also be expressed as attribute/value pairs on the+ object element itself when brevity is desired.+-->++<!ELEMENT object (#PCDATA | param | %block; | form | %inline; | %misc;)*>+<!ATTLIST object+ %attrs;+ declare (declare) #IMPLIED+ classid %URI; #IMPLIED+ codebase %URI; #IMPLIED+ data %URI; #IMPLIED+ type %ContentType; #IMPLIED+ codetype %ContentType; #IMPLIED+ archive %UriList; #IMPLIED+ standby %Text; #IMPLIED+ height %Length; #IMPLIED+ width %Length; #IMPLIED+ usemap %URI; #IMPLIED+ name NMTOKEN #IMPLIED+ tabindex %Number; #IMPLIED+ >++<!--+ param is used to supply a named property value.+ In XML it would seem natural to follow RDF and support an+ abbreviated syntax where the param elements are replaced+ by attribute value pairs on the object start tag.+-->+<!ELEMENT param EMPTY>+<!ATTLIST param+ id ID #IMPLIED+ name CDATA #IMPLIED+ value CDATA #IMPLIED+ valuetype (data|ref|object) "data"+ type %ContentType; #IMPLIED+ >++<!--=================== Images ===========================================-->++<!--+ To avoid accessibility problems for people who aren't+ able to see the image, you should provide a text+ description using the alt and longdesc attributes.+ In addition, avoid the use of server-side image maps.+ Note that in this DTD there is no name attribute. That+ is only available in the transitional and frameset DTD.+-->++<!ELEMENT img EMPTY>+<!ATTLIST img+ %attrs;+ src %URI; #REQUIRED+ alt %Text; #REQUIRED+ longdesc %URI; #IMPLIED+ height %Length; #IMPLIED+ width %Length; #IMPLIED+ usemap %URI; #IMPLIED+ ismap (ismap) #IMPLIED+ >++<!-- usemap points to a map element which may be in this document+ or an external document, although the latter is not widely supported -->++<!--================== Client-side image maps ============================-->++<!-- These can be placed in the same document or grouped in a+ separate document although this isn't yet widely supported -->++<!ELEMENT map ((%block; | form | %misc;)+ | area+)>+<!ATTLIST map+ %i18n;+ %events;+ id ID #REQUIRED+ class CDATA #IMPLIED+ style %StyleSheet; #IMPLIED+ title %Text; #IMPLIED+ name NMTOKEN #IMPLIED+ >++<!ELEMENT area EMPTY>+<!ATTLIST area+ %attrs;+ shape %Shape; "rect"+ coords %Coords; #IMPLIED+ href %URI; #IMPLIED+ nohref (nohref) #IMPLIED+ alt %Text; #REQUIRED+ tabindex %Number; #IMPLIED+ accesskey %Character; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED+ >++<!--================ Forms ===============================================-->+<!ELEMENT form %form.content;> <!-- forms shouldn't be nested -->++<!ATTLIST form+ %attrs;+ action %URI; #REQUIRED+ method (get|post) "get"+ enctype %ContentType; "application/x-www-form-urlencoded"+ onsubmit %Script; #IMPLIED+ onreset %Script; #IMPLIED+ accept %ContentTypes; #IMPLIED+ accept-charset %Charsets; #IMPLIED+ >++<!--+ Each label must not contain more than ONE field+ Label elements shouldn't be nested.+-->+<!ELEMENT label %Inline;>+<!ATTLIST label+ %attrs;+ for IDREF #IMPLIED+ accesskey %Character; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED+ >++<!ENTITY % InputType+ "(text | password | checkbox |+ radio | submit | reset |+ file | hidden | image | button)"+ >++<!-- the name attribute is required for all but submit & reset -->++<!ELEMENT input EMPTY> <!-- form control -->+<!ATTLIST input+ %attrs;+ type %InputType; "text"+ name CDATA #IMPLIED+ value CDATA #IMPLIED+ checked (checked) #IMPLIED+ disabled (disabled) #IMPLIED+ readonly (readonly) #IMPLIED+ size CDATA #IMPLIED+ maxlength %Number; #IMPLIED+ src %URI; #IMPLIED+ alt CDATA #IMPLIED+ usemap %URI; #IMPLIED+ tabindex %Number; #IMPLIED+ accesskey %Character; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED+ onselect %Script; #IMPLIED+ onchange %Script; #IMPLIED+ accept %ContentTypes; #IMPLIED+ >++<!ELEMENT select (optgroup|option)+> <!-- option selector -->+<!ATTLIST select+ %attrs;+ name CDATA #IMPLIED+ size %Number; #IMPLIED+ multiple (multiple) #IMPLIED+ disabled (disabled) #IMPLIED+ tabindex %Number; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED+ onchange %Script; #IMPLIED+ >++<!ELEMENT optgroup (option)+> <!-- option group -->+<!ATTLIST optgroup+ %attrs;+ disabled (disabled) #IMPLIED+ label %Text; #REQUIRED+ >++<!ELEMENT option (#PCDATA)> <!-- selectable choice -->+<!ATTLIST option+ %attrs;+ selected (selected) #IMPLIED+ disabled (disabled) #IMPLIED+ label %Text; #IMPLIED+ value CDATA #IMPLIED+ >++<!ELEMENT textarea (#PCDATA)> <!-- multi-line text field -->+<!ATTLIST textarea+ %attrs;+ name CDATA #IMPLIED+ rows %Number; #REQUIRED+ cols %Number; #REQUIRED+ disabled (disabled) #IMPLIED+ readonly (readonly) #IMPLIED+ tabindex %Number; #IMPLIED+ accesskey %Character; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED+ onselect %Script; #IMPLIED+ onchange %Script; #IMPLIED+ >++<!--+ The fieldset element is used to group form fields.+ Only one legend element should occur in the content+ and if present should only be preceded by whitespace.+-->+<!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*>+<!ATTLIST fieldset+ %attrs;+ >++<!ELEMENT legend %Inline;> <!-- fieldset label -->+<!ATTLIST legend+ %attrs;+ accesskey %Character; #IMPLIED+ >++<!--+ Content is %Flow; excluding a, form and form controls+--> +<!ELEMENT button %button.content;> <!-- push button -->+<!ATTLIST button+ %attrs;+ name CDATA #IMPLIED+ value CDATA #IMPLIED+ type (button|submit|reset) "submit"+ disabled (disabled) #IMPLIED+ tabindex %Number; #IMPLIED+ accesskey %Character; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED+ >++<!--======================= Tables =======================================-->++<!-- Derived from IETF HTML table standard, see [RFC1942] -->++<!--+ The border attribute sets the thickness of the frame around the+ table. The default units are screen pixels.++ The frame attribute specifies which parts of the frame around+ the table should be rendered. The values are not the same as+ CALS to avoid a name clash with the valign attribute.+-->+<!ENTITY % TFrame "(void|above|below|hsides|lhs|rhs|vsides|box|border)">++<!--+ The rules attribute defines which rules to draw between cells:++ If rules is absent then assume:+ "none" if border is absent or border="0" otherwise "all"+-->++<!ENTITY % TRules "(none | groups | rows | cols | all)">+ +<!-- horizontal placement of table relative to document -->+<!ENTITY % TAlign "(left|center|right)">++<!-- horizontal alignment attributes for cell contents++ char alignment char, e.g. char=':'+ charoff offset for alignment char+-->+<!ENTITY % cellhalign+ "align (left|center|right|justify|char) #IMPLIED+ char %Character; #IMPLIED+ charoff %Length; #IMPLIED"+ >++<!-- vertical alignment attributes for cell contents -->+<!ENTITY % cellvalign+ "valign (top|middle|bottom|baseline) #IMPLIED"+ >++<!ELEMENT table+ (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))>+<!ELEMENT caption %Inline;>+<!ELEMENT thead (tr)+>+<!ELEMENT tfoot (tr)+>+<!ELEMENT tbody (tr)+>+<!ELEMENT colgroup (col)*>+<!ELEMENT col EMPTY>+<!ELEMENT tr (th|td)+>+<!ELEMENT th %Flow;>+<!ELEMENT td %Flow;>++<!ATTLIST table+ %attrs;+ summary %Text; #IMPLIED+ width %Length; #IMPLIED+ border %Pixels; #IMPLIED+ frame %TFrame; #IMPLIED+ rules %TRules; #IMPLIED+ cellspacing %Length; #IMPLIED+ cellpadding %Length; #IMPLIED+ >++<!ENTITY % CAlign "(top|bottom|left|right)">++<!ATTLIST caption+ %attrs;+ >++<!--+colgroup groups a set of col elements. It allows you to group+several semantically related columns together.+-->+<!ATTLIST colgroup+ %attrs;+ span %Number; "1"+ width %MultiLength; #IMPLIED+ %cellhalign;+ %cellvalign;+ >++<!--+ col elements define the alignment properties for cells in+ one or more columns.++ The width attribute specifies the width of the columns, e.g.++ width=64 width in screen pixels+ width=0.5* relative width of 0.5++ The span attribute causes the attributes of one+ col element to apply to more than one column.+-->+<!ATTLIST col+ %attrs;+ span %Number; "1"+ width %MultiLength; #IMPLIED+ %cellhalign;+ %cellvalign;+ >++<!--+ Use thead to duplicate headers when breaking table+ across page boundaries, or for static headers when+ tbody sections are rendered in scrolling panel.++ Use tfoot to duplicate footers when breaking table+ across page boundaries, or for static footers when+ tbody sections are rendered in scrolling panel.++ Use multiple tbody sections when rules are needed+ between groups of table rows.+-->+<!ATTLIST thead+ %attrs;+ %cellhalign;+ %cellvalign;+ >++<!ATTLIST tfoot+ %attrs;+ %cellhalign;+ %cellvalign;+ >++<!ATTLIST tbody+ %attrs;+ %cellhalign;+ %cellvalign;+ >++<!ATTLIST tr+ %attrs;+ %cellhalign;+ %cellvalign;+ >+++<!-- Scope is simpler than headers attribute for common tables -->+<!ENTITY % Scope "(row|col|rowgroup|colgroup)">++<!-- th is for headers, td for data and for cells acting as both -->++<!ATTLIST th+ %attrs;+ abbr %Text; #IMPLIED+ axis CDATA #IMPLIED+ headers IDREFS #IMPLIED+ scope %Scope; #IMPLIED+ rowspan %Number; "1"+ colspan %Number; "1"+ %cellhalign;+ %cellvalign;+ >++<!ATTLIST td+ %attrs;+ abbr %Text; #IMPLIED+ axis CDATA #IMPLIED+ headers IDREFS #IMPLIED+ scope %Scope; #IMPLIED+ rowspan %Number; "1"+ colspan %Number; "1"+ %cellhalign;+ %cellvalign;+ >+
+ examples/hxpath/xhtml/xhtml1-transitional.dtd view
@@ -0,0 +1,1196 @@+<!--+ Extensible HTML version 1.0 Transitional DTD++ This is the same as HTML 4.0 Transitional except for+ changes due to the differences between XML and SGML.++ Namespace = http://www.w3.org/1999/xhtml++ For further information, see: http://www.w3.org/TR/xhtml1++ Copyright (c) 1998-2000 W3C (MIT, INRIA, Keio),+ All Rights Reserved. ++ This DTD module is identified by the PUBLIC and SYSTEM identifiers:++ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"+ SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"++ $Revision: 1.1 $+ $Date: 2002/10/01 13:47:08 $++-->++<!--================ Character mnemonic entities =========================-->++<!ENTITY % HTMLlat1 PUBLIC+ "-//W3C//ENTITIES Latin 1 for XHTML//EN"+ "xhtml-lat1.ent">+%HTMLlat1;++<!ENTITY % HTMLsymbol PUBLIC+ "-//W3C//ENTITIES Symbols for XHTML//EN"+ "xhtml-symbol.ent">+%HTMLsymbol;++<!ENTITY % HTMLspecial PUBLIC+ "-//W3C//ENTITIES Special for XHTML//EN"+ "xhtml-special.ent">+%HTMLspecial;++<!--================== Imported Names ====================================-->++<!ENTITY % ContentType "CDATA">+ <!-- media type, as per [RFC2045] -->++<!ENTITY % ContentTypes "CDATA">+ <!-- comma-separated list of media types, as per [RFC2045] -->++<!ENTITY % Charset "CDATA">+ <!-- a character encoding, as per [RFC2045] -->++<!ENTITY % Charsets "CDATA">+ <!-- a space separated list of character encodings, as per [RFC2045] -->++<!ENTITY % LanguageCode "NMTOKEN">+ <!-- a language code, as per [RFC1766] -->++<!ENTITY % Character "CDATA">+ <!-- a single character from [ISO10646] -->++<!ENTITY % Number "CDATA">+ <!-- one or more digits -->++<!ENTITY % LinkTypes "CDATA">+ <!-- space-separated list of link types -->++<!ENTITY % MediaDesc "CDATA">+ <!-- single or comma-separated list of media descriptors -->++<!ENTITY % URI "CDATA">+ <!-- a Uniform Resource Identifier, see [RFC2396] -->++<!ENTITY % UriList "CDATA">+ <!-- a space separated list of Uniform Resource Identifiers -->++<!ENTITY % Datetime "CDATA">+ <!-- date and time information. ISO date format -->++<!ENTITY % Script "CDATA">+ <!-- script expression -->++<!ENTITY % StyleSheet "CDATA">+ <!-- style sheet data -->++<!ENTITY % Text "CDATA">+ <!-- used for titles etc. -->++<!ENTITY % FrameTarget "NMTOKEN">+ <!-- render in this frame -->++<!ENTITY % Length "CDATA">+ <!-- nn for pixels or nn% for percentage length -->++<!ENTITY % MultiLength "CDATA">+ <!-- pixel, percentage, or relative -->++<!ENTITY % MultiLengths "CDATA">+ <!-- comma-separated list of MultiLength -->++<!ENTITY % Pixels "CDATA">+ <!-- integer representing length in pixels -->++<!-- these are used for image maps -->++<!ENTITY % Shape "(rect|circle|poly|default)">++<!ENTITY % Coords "CDATA">+ <!-- comma separated list of lengths -->++<!-- used for object, applet, img, input and iframe -->+<!ENTITY % ImgAlign "(top|middle|bottom|left|right)">++<!-- a color using sRGB: #RRGGBB as Hex values -->+<!ENTITY % Color "CDATA">++<!-- There are also 16 widely known color names with their sRGB values:++ Black = #000000 Green = #008000+ Silver = #C0C0C0 Lime = #00FF00+ Gray = #808080 Olive = #808000+ White = #FFFFFF Yellow = #FFFF00+ Maroon = #800000 Navy = #000080+ Red = #FF0000 Blue = #0000FF+ Purple = #800080 Teal = #008080+ Fuchsia= #FF00FF Aqua = #00FFFF+-->++<!--=================== Generic Attributes ===============================-->++<!-- core attributes common to most elements+ id document-wide unique id+ class space separated list of classes+ style associated style info+ title advisory title/amplification+-->+<!ENTITY % coreattrs+ "id ID #IMPLIED+ class CDATA #IMPLIED+ style %StyleSheet; #IMPLIED+ title %Text; #IMPLIED"+ >++<!-- internationalization attributes+ lang language code (backwards compatible)+ xml:lang language code (as per XML 1.0 spec)+ dir direction for weak/neutral text+-->+<!ENTITY % i18n+ "lang %LanguageCode; #IMPLIED+ xml:lang %LanguageCode; #IMPLIED+ dir (ltr|rtl) #IMPLIED"+ >++<!-- attributes for common UI events+ onclick a pointer button was clicked+ ondblclick a pointer button was double clicked+ onmousedown a pointer button was pressed down+ onmouseup a pointer button was released+ onmousemove a pointer was moved onto the element+ onmouseout a pointer was moved away from the element+ onkeypress a key was pressed and released+ onkeydown a key was pressed down+ onkeyup a key was released+-->+<!ENTITY % events+ "onclick %Script; #IMPLIED+ ondblclick %Script; #IMPLIED+ onmousedown %Script; #IMPLIED+ onmouseup %Script; #IMPLIED+ onmouseover %Script; #IMPLIED+ onmousemove %Script; #IMPLIED+ onmouseout %Script; #IMPLIED+ onkeypress %Script; #IMPLIED+ onkeydown %Script; #IMPLIED+ onkeyup %Script; #IMPLIED"+ >++<!-- attributes for elements that can get the focus+ accesskey accessibility key character+ tabindex position in tabbing order+ onfocus the element got the focus+ onblur the element lost the focus+-->+<!ENTITY % focus+ "accesskey %Character; #IMPLIED+ tabindex %Number; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED"+ >++<!ENTITY % attrs "%coreattrs; %i18n; %events;">++<!-- text alignment for p, div, h1-h6. The default is+ align="left" for ltr headings, "right" for rtl -->++<!ENTITY % TextAlign "align (left|center|right) #IMPLIED">++<!--=================== Text Elements ====================================-->++<!ENTITY % special+ "br | span | bdo | object | applet | img | map | iframe">++<!ENTITY % fontstyle "tt | i | b | big | small | u+ | s | strike |font | basefont">++<!ENTITY % phrase "em | strong | dfn | code | q | sub | sup |+ samp | kbd | var | cite | abbr | acronym">++<!ENTITY % inline.forms "input | select | textarea | label | button">++<!-- these can occur at block or inline level -->+<!ENTITY % misc "ins | del | script | noscript">++<!ENTITY % inline "a | %special; | %fontstyle; | %phrase; | %inline.forms;">++<!-- %Inline; covers inline or "text-level" elements -->+<!ENTITY % Inline "(#PCDATA | %inline; | %misc;)*">++<!--================== Block level elements ==============================-->++<!ENTITY % heading "h1|h2|h3|h4|h5|h6">+<!ENTITY % lists "ul | ol | dl | menu | dir">+<!ENTITY % blocktext "pre | hr | blockquote | address | center | noframes">++<!ENTITY % block+ "p | %heading; | div | %lists; | %blocktext; | isindex |fieldset | table">++<!ENTITY % Block "(%block; | form | %misc;)*">++<!-- %Flow; mixes Block and Inline and is used for list items etc. -->+<!ENTITY % Flow "(#PCDATA | %block; | form | %inline; | %misc;)*">++<!--================== Content models for exclusions =====================-->++<!-- a elements use %Inline; excluding a -->++<!ENTITY % a.content+ "(#PCDATA | %special; | %fontstyle; | %phrase; | %inline.forms; | %misc;)*">++<!-- pre uses %Inline excluding img, object, applet, big, small,+ sub, sup, font, or basefont -->++<!ENTITY % pre.content+ "(#PCDATA | a | br | span | bdo | map | tt | i | b | u | s |+ %phrase; | %inline.forms;)*">++<!-- form uses %Flow; excluding form -->++<!ENTITY % form.content "(#PCDATA | %block; | %inline; | %misc;)*">++<!-- button uses %Flow; but excludes a, form, form controls, iframe -->++<!ENTITY % button.content+ "(#PCDATA | p | %heading; | div | %lists; | %blocktext; |+ table | br | span | bdo | object | applet | img | map |+ %fontstyle; | %phrase; | %misc;)*">++<!--================ Document Structure ==================================-->++<!-- the namespace URI designates the document profile -->++<!ELEMENT html (head, body)>+<!ATTLIST html+ %i18n;+ xmlns %URI; #FIXED 'http://www.w3.org/1999/xhtml'+ >++<!--================ Document Head =======================================-->++<!ENTITY % head.misc "(script|style|meta|link|object|isindex)*">++<!-- content model is %head.misc; combined with a single+ title and an optional base element in any order -->++<!ELEMENT head (%head.misc;,+ ((title, %head.misc;, (base, %head.misc;)?) |+ (base, %head.misc;, (title, %head.misc;))))>++<!ATTLIST head+ %i18n;+ profile %URI; #IMPLIED+ >++<!-- The title element is not considered part of the flow of text.+ It should be displayed, for example as the page header or+ window title. Exactly one title is required per document.+ -->+<!ELEMENT title (#PCDATA)>+<!ATTLIST title %i18n;>++<!-- document base URI -->++<!ELEMENT base EMPTY>+<!ATTLIST base+ href %URI; #IMPLIED+ target %FrameTarget; #IMPLIED+ >++<!-- generic metainformation -->+<!ELEMENT meta EMPTY>+<!ATTLIST meta+ %i18n;+ http-equiv CDATA #IMPLIED+ name CDATA #IMPLIED+ content CDATA #REQUIRED+ scheme CDATA #IMPLIED+ >++<!--+ Relationship values can be used in principle:++ a) for document specific toolbars/menus when used+ with the link element in document head e.g.+ start, contents, previous, next, index, end, help+ b) to link to a separate style sheet (rel="stylesheet")+ c) to make a link to a script (rel="script")+ d) by stylesheets to control how collections of+ html nodes are rendered into printed documents+ e) to make a link to a printable version of this document+ e.g. a PostScript or PDF version (rel="alternate" media="print")+-->++<!ELEMENT link EMPTY>+<!ATTLIST link+ %attrs;+ charset %Charset; #IMPLIED+ href %URI; #IMPLIED+ hreflang %LanguageCode; #IMPLIED+ type %ContentType; #IMPLIED+ rel %LinkTypes; #IMPLIED+ rev %LinkTypes; #IMPLIED+ media %MediaDesc; #IMPLIED+ target %FrameTarget; #IMPLIED+ >++<!-- style info, which may include CDATA sections -->+<!ELEMENT style (#PCDATA)>+<!ATTLIST style+ %i18n;+ type %ContentType; #REQUIRED+ media %MediaDesc; #IMPLIED+ title %Text; #IMPLIED+ xml:space (preserve) #FIXED 'preserve'+ >++<!-- script statements, which may include CDATA sections -->+<!ELEMENT script (#PCDATA)>+<!ATTLIST script+ charset %Charset; #IMPLIED+ type %ContentType; #REQUIRED+ language CDATA #IMPLIED+ src %URI; #IMPLIED+ defer (defer) #IMPLIED+ xml:space (preserve) #FIXED 'preserve'+ >++<!-- alternate content container for non script-based rendering -->++<!ELEMENT noscript %Flow;>+<!ATTLIST noscript+ %attrs;+ >++<!--======================= Frames =======================================-->++<!-- inline subwindow -->++<!ELEMENT iframe %Flow;>+<!ATTLIST iframe+ %coreattrs;+ longdesc %URI; #IMPLIED+ name NMTOKEN #IMPLIED+ src %URI; #IMPLIED+ frameborder (1|0) "1"+ marginwidth %Pixels; #IMPLIED+ marginheight %Pixels; #IMPLIED+ scrolling (yes|no|auto) "auto"+ align %ImgAlign; #IMPLIED+ height %Length; #IMPLIED+ width %Length; #IMPLIED+ >++<!-- alternate content container for non frame-based rendering -->++<!ELEMENT noframes %Flow;>+<!ATTLIST noframes+ %attrs;+ >++<!--=================== Document Body ====================================-->++<!ELEMENT body %Flow;>+<!ATTLIST body+ %attrs;+ onload %Script; #IMPLIED+ onunload %Script; #IMPLIED+ background %URI; #IMPLIED+ bgcolor %Color; #IMPLIED+ text %Color; #IMPLIED+ link %Color; #IMPLIED+ vlink %Color; #IMPLIED+ alink %Color; #IMPLIED+ >++<!ELEMENT div %Flow;> <!-- generic language/style container -->+<!ATTLIST div+ %attrs;+ %TextAlign;+ >++<!--=================== Paragraphs =======================================-->++<!ELEMENT p %Inline;>+<!ATTLIST p+ %attrs;+ %TextAlign;+ >++<!--=================== Headings =========================================-->++<!--+ There are six levels of headings from h1 (the most important)+ to h6 (the least important).+-->++<!ELEMENT h1 %Inline;>+<!ATTLIST h1+ %attrs;+ %TextAlign;+ >++<!ELEMENT h2 %Inline;>+<!ATTLIST h2+ %attrs;+ %TextAlign;+ >++<!ELEMENT h3 %Inline;>+<!ATTLIST h3+ %attrs;+ %TextAlign;+ >++<!ELEMENT h4 %Inline;>+<!ATTLIST h4+ %attrs;+ %TextAlign;+ >++<!ELEMENT h5 %Inline;>+<!ATTLIST h5+ %attrs;+ %TextAlign;+ >++<!ELEMENT h6 %Inline;>+<!ATTLIST h6+ %attrs;+ %TextAlign;+ >++<!--=================== Lists ============================================-->++<!-- Unordered list bullet styles -->++<!ENTITY % ULStyle "(disc|square|circle)">++<!-- Unordered list -->++<!ELEMENT ul (li)+>+<!ATTLIST ul+ %attrs;+ type %ULStyle; #IMPLIED+ compact (compact) #IMPLIED+ >++<!-- Ordered list numbering style++ 1 arabic numbers 1, 2, 3, ...+ a lower alpha a, b, c, ...+ A upper alpha A, B, C, ...+ i lower roman i, ii, iii, ...+ I upper roman I, II, III, ...++ The style is applied to the sequence number which by default+ is reset to 1 for the first list item in an ordered list.+-->+<!ENTITY % OLStyle "CDATA">++<!-- Ordered (numbered) list -->++<!ELEMENT ol (li)+>+<!ATTLIST ol+ %attrs;+ type %OLStyle; #IMPLIED+ compact (compact) #IMPLIED+ start %Number; #IMPLIED+ >++<!-- single column list (DEPRECATED) --> +<!ELEMENT menu (li)+>+<!ATTLIST menu+ %attrs;+ compact (compact) #IMPLIED+ >++<!-- multiple column list (DEPRECATED) --> +<!ELEMENT dir (li)+>+<!ATTLIST dir+ %attrs;+ compact (compact) #IMPLIED+ >++<!-- LIStyle is constrained to: "(%ULStyle;|%OLStyle;)" -->+<!ENTITY % LIStyle "CDATA">++<!-- list item -->++<!ELEMENT li %Flow;>+<!ATTLIST li+ %attrs;+ type %LIStyle; #IMPLIED+ value %Number; #IMPLIED+ >++<!-- definition lists - dt for term, dd for its definition -->++<!ELEMENT dl (dt|dd)+>+<!ATTLIST dl+ %attrs;+ compact (compact) #IMPLIED+ >++<!ELEMENT dt %Inline;>+<!ATTLIST dt+ %attrs;+ >++<!ELEMENT dd %Flow;>+<!ATTLIST dd+ %attrs;+ >++<!--=================== Address ==========================================-->++<!-- information on author -->++<!ELEMENT address %Inline;>+<!ATTLIST address+ %attrs;+ >++<!--=================== Horizontal Rule ==================================-->++<!ELEMENT hr EMPTY>+<!ATTLIST hr+ %attrs;+ align (left|center|right) #IMPLIED+ noshade (noshade) #IMPLIED+ size %Pixels; #IMPLIED+ width %Length; #IMPLIED+ >++<!--=================== Preformatted Text ================================-->++<!-- content is %Inline; excluding + "img|object|applet|big|small|sub|sup|font|basefont" -->++<!ELEMENT pre %pre.content;>+<!ATTLIST pre+ %attrs;+ width %Number; #IMPLIED+ xml:space (preserve) #FIXED 'preserve'+ >++<!--=================== Block-like Quotes ================================-->++<!ELEMENT blockquote %Flow;>+<!ATTLIST blockquote+ %attrs;+ cite %URI; #IMPLIED+ >++<!--=================== Text alignment ===================================-->++<!-- center content -->+<!ELEMENT center %Flow;>+<!ATTLIST center+ %attrs;+ >++<!--=================== Inserted/Deleted Text ============================-->++<!--+ ins/del are allowed in block and inline content, but its+ inappropriate to include block content within an ins element+ occurring in inline content.+-->+<!ELEMENT ins %Flow;>+<!ATTLIST ins+ %attrs;+ cite %URI; #IMPLIED+ datetime %Datetime; #IMPLIED+ >++<!ELEMENT del %Flow;>+<!ATTLIST del+ %attrs;+ cite %URI; #IMPLIED+ datetime %Datetime; #IMPLIED+ >++<!--================== The Anchor Element ================================-->++<!-- content is %Inline; except that anchors shouldn't be nested -->++<!ELEMENT a %a.content;>+<!ATTLIST a+ %attrs;+ charset %Charset; #IMPLIED+ type %ContentType; #IMPLIED+ name NMTOKEN #IMPLIED+ href %URI; #IMPLIED+ hreflang %LanguageCode; #IMPLIED+ rel %LinkTypes; #IMPLIED+ rev %LinkTypes; #IMPLIED+ accesskey %Character; #IMPLIED+ shape %Shape; "rect"+ coords %Coords; #IMPLIED+ tabindex %Number; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED+ target %FrameTarget; #IMPLIED+ >++<!--===================== Inline Elements ================================-->++<!ELEMENT span %Inline;> <!-- generic language/style container -->+<!ATTLIST span+ %attrs;+ >++<!ELEMENT bdo %Inline;> <!-- I18N BiDi over-ride -->+<!ATTLIST bdo+ %coreattrs;+ %events;+ lang %LanguageCode; #IMPLIED+ xml:lang %LanguageCode; #IMPLIED+ dir (ltr|rtl) #REQUIRED+ >++<!ELEMENT br EMPTY> <!-- forced line break -->+<!ATTLIST br+ %coreattrs;+ clear (left|all|right|none) "none"+ >++<!ELEMENT em %Inline;> <!-- emphasis -->+<!ATTLIST em %attrs;>++<!ELEMENT strong %Inline;> <!-- strong emphasis -->+<!ATTLIST strong %attrs;>++<!ELEMENT dfn %Inline;> <!-- definitional -->+<!ATTLIST dfn %attrs;>++<!ELEMENT code %Inline;> <!-- program code -->+<!ATTLIST code %attrs;>++<!ELEMENT samp %Inline;> <!-- sample -->+<!ATTLIST samp %attrs;>++<!ELEMENT kbd %Inline;> <!-- something user would type -->+<!ATTLIST kbd %attrs;>++<!ELEMENT var %Inline;> <!-- variable -->+<!ATTLIST var %attrs;>++<!ELEMENT cite %Inline;> <!-- citation -->+<!ATTLIST cite %attrs;>++<!ELEMENT abbr %Inline;> <!-- abbreviation -->+<!ATTLIST abbr %attrs;>++<!ELEMENT acronym %Inline;> <!-- acronym -->+<!ATTLIST acronym %attrs;>++<!ELEMENT q %Inline;> <!-- inlined quote -->+<!ATTLIST q+ %attrs;+ cite %URI; #IMPLIED+ >++<!ELEMENT sub %Inline;> <!-- subscript -->+<!ATTLIST sub %attrs;>++<!ELEMENT sup %Inline;> <!-- superscript -->+<!ATTLIST sup %attrs;>++<!ELEMENT tt %Inline;> <!-- fixed pitch font -->+<!ATTLIST tt %attrs;>++<!ELEMENT i %Inline;> <!-- italic font -->+<!ATTLIST i %attrs;>++<!ELEMENT b %Inline;> <!-- bold font -->+<!ATTLIST b %attrs;>++<!ELEMENT big %Inline;> <!-- bigger font -->+<!ATTLIST big %attrs;>++<!ELEMENT small %Inline;> <!-- smaller font -->+<!ATTLIST small %attrs;>++<!ELEMENT u %Inline;> <!-- underline -->+<!ATTLIST u %attrs;>++<!ELEMENT s %Inline;> <!-- strike-through -->+<!ATTLIST s %attrs;>++<!ELEMENT strike %Inline;> <!-- strike-through -->+<!ATTLIST strike %attrs;>++<!ELEMENT basefont EMPTY> <!-- base font size -->+<!ATTLIST basefont+ id ID #IMPLIED+ size CDATA #REQUIRED+ color %Color; #IMPLIED+ face CDATA #IMPLIED+ >++<!ELEMENT font %Inline;> <!-- local change to font -->+<!ATTLIST font+ %coreattrs;+ %i18n;+ size CDATA #IMPLIED+ color %Color; #IMPLIED+ face CDATA #IMPLIED+ >++<!--==================== Object ======================================-->+<!--+ object is used to embed objects as part of HTML pages.+ param elements should precede other content. Parameters+ can also be expressed as attribute/value pairs on the+ object element itself when brevity is desired.+-->++<!ELEMENT object (#PCDATA | param | %block; | form | %inline; | %misc;)*>+<!ATTLIST object+ %attrs;+ declare (declare) #IMPLIED+ classid %URI; #IMPLIED+ codebase %URI; #IMPLIED+ data %URI; #IMPLIED+ type %ContentType; #IMPLIED+ codetype %ContentType; #IMPLIED+ archive %UriList; #IMPLIED+ standby %Text; #IMPLIED+ height %Length; #IMPLIED+ width %Length; #IMPLIED+ usemap %URI; #IMPLIED+ name NMTOKEN #IMPLIED+ tabindex %Number; #IMPLIED+ align %ImgAlign; #IMPLIED+ border %Pixels; #IMPLIED+ hspace %Pixels; #IMPLIED+ vspace %Pixels; #IMPLIED+ >++<!--+ param is used to supply a named property value.+ In XML it would seem natural to follow RDF and support an+ abbreviated syntax where the param elements are replaced+ by attribute value pairs on the object start tag.+-->+<!ELEMENT param EMPTY>+<!ATTLIST param+ id ID #IMPLIED+ name CDATA #REQUIRED+ value CDATA #IMPLIED+ valuetype (data|ref|object) "data"+ type %ContentType; #IMPLIED+ >++<!--=================== Java applet ==================================-->+<!--+ One of code or object attributes must be present.+ Place param elements before other content.+-->+<!ELEMENT applet (#PCDATA | param | %block; | form | %inline; | %misc;)*>+<!ATTLIST applet+ %coreattrs;+ codebase %URI; #IMPLIED+ archive CDATA #IMPLIED+ code CDATA #IMPLIED+ object CDATA #IMPLIED+ alt %Text; #IMPLIED+ name NMTOKEN #IMPLIED+ width %Length; #REQUIRED+ height %Length; #REQUIRED+ align %ImgAlign; #IMPLIED+ hspace %Pixels; #IMPLIED+ vspace %Pixels; #IMPLIED+ >++<!--=================== Images ===========================================-->++<!--+ To avoid accessibility problems for people who aren't+ able to see the image, you should provide a text+ description using the alt and longdesc attributes.+ In addition, avoid the use of server-side image maps.+-->++<!ELEMENT img EMPTY>+<!ATTLIST img+ %attrs;+ src %URI; #REQUIRED+ alt %Text; #REQUIRED+ name NMTOKEN #IMPLIED+ longdesc %URI; #IMPLIED+ height %Length; #IMPLIED+ width %Length; #IMPLIED+ usemap %URI; #IMPLIED+ ismap (ismap) #IMPLIED+ align %ImgAlign; #IMPLIED+ border %Length; #IMPLIED+ hspace %Pixels; #IMPLIED+ vspace %Pixels; #IMPLIED+ >++<!-- usemap points to a map element which may be in this document+ or an external document, although the latter is not widely supported -->++<!--================== Client-side image maps ============================-->++<!-- These can be placed in the same document or grouped in a+ separate document although this isn't yet widely supported -->++<!ELEMENT map ((%block; | form | %misc;)+ | area+)>+<!ATTLIST map+ %i18n;+ %events;+ id ID #REQUIRED+ class CDATA #IMPLIED+ style %StyleSheet; #IMPLIED+ title %Text; #IMPLIED+ name CDATA #IMPLIED+ >++<!ELEMENT area EMPTY>+<!ATTLIST area+ %attrs;+ shape %Shape; "rect"+ coords %Coords; #IMPLIED+ href %URI; #IMPLIED+ nohref (nohref) #IMPLIED+ alt %Text; #REQUIRED+ tabindex %Number; #IMPLIED+ accesskey %Character; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED+ target %FrameTarget; #IMPLIED+ >++<!--================ Forms ===============================================-->++<!ELEMENT form %form.content;> <!-- forms shouldn't be nested -->++<!ATTLIST form+ %attrs;+ action %URI; #REQUIRED+ method (get|post) "get"+ name NMTOKEN #IMPLIED+ enctype %ContentType; "application/x-www-form-urlencoded"+ onsubmit %Script; #IMPLIED+ onreset %Script; #IMPLIED+ accept %ContentTypes; #IMPLIED+ accept-charset %Charsets; #IMPLIED+ target %FrameTarget; #IMPLIED+ >++<!--+ Each label must not contain more than ONE field+ Label elements shouldn't be nested.+-->+<!ELEMENT label %Inline;>+<!ATTLIST label+ %attrs;+ for IDREF #IMPLIED+ accesskey %Character; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED+ >++<!ENTITY % InputType+ "(text | password | checkbox |+ radio | submit | reset |+ file | hidden | image | button)"+ >++<!-- the name attribute is required for all but submit & reset -->++<!ELEMENT input EMPTY> <!-- form control -->+<!ATTLIST input+ %attrs;+ type %InputType; "text"+ name CDATA #IMPLIED+ value CDATA #IMPLIED+ checked (checked) #IMPLIED+ disabled (disabled) #IMPLIED+ readonly (readonly) #IMPLIED+ size CDATA #IMPLIED+ maxlength %Number; #IMPLIED+ src %URI; #IMPLIED+ alt CDATA #IMPLIED+ usemap %URI; #IMPLIED+ tabindex %Number; #IMPLIED+ accesskey %Character; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED+ onselect %Script; #IMPLIED+ onchange %Script; #IMPLIED+ accept %ContentTypes; #IMPLIED+ align %ImgAlign; #IMPLIED+ >++<!ELEMENT select (optgroup|option)+> <!-- option selector -->+<!ATTLIST select+ %attrs;+ name CDATA #IMPLIED+ size %Number; #IMPLIED+ multiple (multiple) #IMPLIED+ disabled (disabled) #IMPLIED+ tabindex %Number; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED+ onchange %Script; #IMPLIED+ >++<!ELEMENT optgroup (option)+> <!-- option group -->+<!ATTLIST optgroup+ %attrs;+ disabled (disabled) #IMPLIED+ label %Text; #REQUIRED+ >++<!ELEMENT option (#PCDATA)> <!-- selectable choice -->+<!ATTLIST option+ %attrs;+ selected (selected) #IMPLIED+ disabled (disabled) #IMPLIED+ label %Text; #IMPLIED+ value CDATA #IMPLIED+ >++<!ELEMENT textarea (#PCDATA)> <!-- multi-line text field -->+<!ATTLIST textarea+ %attrs;+ name CDATA #IMPLIED+ rows %Number; #REQUIRED+ cols %Number; #REQUIRED+ disabled (disabled) #IMPLIED+ readonly (readonly) #IMPLIED+ tabindex %Number; #IMPLIED+ accesskey %Character; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED+ onselect %Script; #IMPLIED+ onchange %Script; #IMPLIED+ >++<!--+ The fieldset element is used to group form fields.+ Only one legend element should occur in the content+ and if present should only be preceded by whitespace.+-->+<!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*>+<!ATTLIST fieldset+ %attrs;+ >++<!ENTITY % LAlign "(top|bottom|left|right)">++<!ELEMENT legend %Inline;> <!-- fieldset label -->+<!ATTLIST legend+ %attrs;+ accesskey %Character; #IMPLIED+ align %LAlign; #IMPLIED+ >++<!--+ Content is %Flow; excluding a, form, form controls, iframe+--> +<!ELEMENT button %button.content;> <!-- push button -->+<!ATTLIST button+ %attrs;+ name CDATA #IMPLIED+ value CDATA #IMPLIED+ type (button|submit|reset) "submit"+ disabled (disabled) #IMPLIED+ tabindex %Number; #IMPLIED+ accesskey %Character; #IMPLIED+ onfocus %Script; #IMPLIED+ onblur %Script; #IMPLIED+ >++<!-- single-line text input control (DEPRECATED) -->+<!ELEMENT isindex EMPTY>+<!ATTLIST isindex+ %coreattrs;+ %i18n;+ prompt %Text; #IMPLIED+ >++<!--======================= Tables =======================================-->++<!-- Derived from IETF HTML table standard, see [RFC1942] -->++<!--+ The border attribute sets the thickness of the frame around the+ table. The default units are screen pixels.++ The frame attribute specifies which parts of the frame around+ the table should be rendered. The values are not the same as+ CALS to avoid a name clash with the valign attribute.+-->+<!ENTITY % TFrame "(void|above|below|hsides|lhs|rhs|vsides|box|border)">++<!--+ The rules attribute defines which rules to draw between cells:++ If rules is absent then assume:+ "none" if border is absent or border="0" otherwise "all"+-->++<!ENTITY % TRules "(none | groups | rows | cols | all)">+ +<!-- horizontal placement of table relative to document -->+<!ENTITY % TAlign "(left|center|right)">++<!-- horizontal alignment attributes for cell contents++ char alignment char, e.g. char=':'+ charoff offset for alignment char+-->+<!ENTITY % cellhalign+ "align (left|center|right|justify|char) #IMPLIED+ char %Character; #IMPLIED+ charoff %Length; #IMPLIED"+ >++<!-- vertical alignment attributes for cell contents -->+<!ENTITY % cellvalign+ "valign (top|middle|bottom|baseline) #IMPLIED"+ >++<!ELEMENT table+ (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))>+<!ELEMENT caption %Inline;>+<!ELEMENT thead (tr)+>+<!ELEMENT tfoot (tr)+>+<!ELEMENT tbody (tr)+>+<!ELEMENT colgroup (col)*>+<!ELEMENT col EMPTY>+<!ELEMENT tr (th|td)+>+<!ELEMENT th %Flow;>+<!ELEMENT td %Flow;>++<!ATTLIST table+ %attrs;+ summary %Text; #IMPLIED+ width %Length; #IMPLIED+ border %Pixels; #IMPLIED+ frame %TFrame; #IMPLIED+ rules %TRules; #IMPLIED+ cellspacing %Length; #IMPLIED+ cellpadding %Length; #IMPLIED+ align %TAlign; #IMPLIED+ bgcolor %Color; #IMPLIED+ >++<!ENTITY % CAlign "(top|bottom|left|right)">++<!ATTLIST caption+ %attrs;+ align %CAlign; #IMPLIED+ >++<!--+colgroup groups a set of col elements. It allows you to group+several semantically related columns together.+-->+<!ATTLIST colgroup+ %attrs;+ span %Number; "1"+ width %MultiLength; #IMPLIED+ %cellhalign;+ %cellvalign;+ >++<!--+ col elements define the alignment properties for cells in+ one or more columns.++ The width attribute specifies the width of the columns, e.g.++ width=64 width in screen pixels+ width=0.5* relative width of 0.5++ The span attribute causes the attributes of one+ col element to apply to more than one column.+-->+<!ATTLIST col+ %attrs;+ span %Number; "1"+ width %MultiLength; #IMPLIED+ %cellhalign;+ %cellvalign;+ >++<!--+ Use thead to duplicate headers when breaking table+ across page boundaries, or for static headers when+ tbody sections are rendered in scrolling panel.++ Use tfoot to duplicate footers when breaking table+ across page boundaries, or for static footers when+ tbody sections are rendered in scrolling panel.++ Use multiple tbody sections when rules are needed+ between groups of table rows.+-->+<!ATTLIST thead+ %attrs;+ %cellhalign;+ %cellvalign;+ >++<!ATTLIST tfoot+ %attrs;+ %cellhalign;+ %cellvalign;+ >++<!ATTLIST tbody+ %attrs;+ %cellhalign;+ %cellvalign;+ >++<!ATTLIST tr+ %attrs;+ %cellhalign;+ %cellvalign;+ bgcolor %Color; #IMPLIED+ >++<!-- Scope is simpler than headers attribute for common tables -->+<!ENTITY % Scope "(row|col|rowgroup|colgroup)">++<!-- th is for headers, td for data and for cells acting as both -->++<!ATTLIST th+ %attrs;+ abbr %Text; #IMPLIED+ axis CDATA #IMPLIED+ headers IDREFS #IMPLIED+ scope %Scope; #IMPLIED+ rowspan %Number; "1"+ colspan %Number; "1"+ %cellhalign;+ %cellvalign;+ nowrap (nowrap) #IMPLIED+ bgcolor %Color; #IMPLIED+ width %Pixels; #IMPLIED+ height %Pixels; #IMPLIED+ >++<!ATTLIST td+ %attrs;+ abbr %Text; #IMPLIED+ axis CDATA #IMPLIED+ headers IDREFS #IMPLIED+ scope %Scope; #IMPLIED+ rowspan %Number; "1"+ colspan %Number; "1"+ %cellhalign;+ %cellvalign;+ nowrap (nowrap) #IMPLIED+ bgcolor %Color; #IMPLIED+ width %Pixels; #IMPLIED+ height %Pixels; #IMPLIED+ >+
+ hxt-xpath.cabal view
@@ -0,0 +1,62 @@+-- arch-tag: Haskell XML Toolbox XPath Package+name: hxt-xpath+version: 8.5.0+license: OtherLicense+license-file: LICENCE+maintainer: Uwe Schmidt <uwe@fh-wedel.de>+stability: stable+category: XML+synopsis: The XPath modules for HXT.+description: The Haskell XML Toolbox XPath library. Since version 8.5 this library is packed in a separate package.+homepage: http://www.fh-wedel.de/~si/HXmlToolbox/index.html+copyright: Copyright (c) 2005-2010 Uwe Schmidt+build-type: Simple+cabal-version: >=1.6++extra-source-files:+ examples/hunit/HUnitExample.hs+ examples/hunit/Makefile+ examples/hunit/mini1.xml+ examples/hunit/mini2.xml+ examples/hxpath/example1.xml+ examples/hxpath/.ghci+ examples/hxpath/.gitignore+ examples/hxpath/HXPath.hs+ examples/hxpath/Makefile+ examples/hxpath/W3CTestData.hs+ examples/hxpath/xhtml/xhtml1-frameset.dtd+ examples/hxpath/xhtml/xhtml1-strict.dtd+ examples/hxpath/xhtml/xhtml1-transitional.dtd+ examples/hxpath/xhtml/xhtml-lat1.ent+ examples/hxpath/xhtml/xhtml-special.ent+ examples/hxpath/xhtml/xhtml-symbol.ent+ examples/hxpath/xhtml/xhtml.xml+ examples/hxpath/XPathShell.hs+ examples/Makefile++library+ exposed-modules:+ Text.XML.HXT.XPath,+ Text.XML.HXT.XPath.Arrows,+ Text.XML.HXT.XPath.NavTree,+ Text.XML.HXT.XPath.XPathArithmetic,+ Text.XML.HXT.XPath.XPathDataTypes,+ Text.XML.HXT.XPath.XPathEval,+ Text.XML.HXT.XPath.XPathFct,+ Text.XML.HXT.XPath.XPathKeywords,+ Text.XML.HXT.XPath.XPathParser,+ Text.XML.HXT.XPath.XPathToNodeSet,+ Text.XML.HXT.XPath.XPathToString++ hs-source-dirs: src+ ghc-options: -Wall+ extensions: MultiParamTypeClasses DeriveDataTypeable FunctionalDependencies FlexibleInstances++ build-depends: base >= 4.2 && < 5,+ haskell98 >= 1 && < 2,+ containers >= 0.3 && < 1,+ directory >= 1 && < 2,+ filepath >= 1 && < 2,+ parsec >= 2.1 && < 4,+ hxt >= 8.5 && < 9+
+ src/Text/XML/HXT/XPath.hs view
@@ -0,0 +1,19 @@+-- | +-- This helper module exports elements from the basic libraries: +-- XPathEval, XPathToString and XPathParser +-- +-- Author : Torben Kuseler + + +module Text.XML.HXT.XPath + ( module Text.XML.HXT.XPath.XPathEval + , module Text.XML.HXT.XPath.XPathToString + , module Text.XML.HXT.XPath.XPathParser + , module Text.XML.HXT.XPath.Arrows + ) +where + +import Text.XML.HXT.XPath.XPathEval +import Text.XML.HXT.XPath.XPathToString +import Text.XML.HXT.XPath.XPathParser +import Text.XML.HXT.XPath.Arrows
+ src/Text/XML/HXT/XPath/Arrows.hs view
@@ -0,0 +1,292 @@+-- ------------------------------------------------------------++{- |+ Module : Text.XML.HXT.XPath.Arrows+ Copyright : Copyright (C) 2006-infinity Uwe Schmidt+ License : MIT++ Maintainer : Uwe Schmidt (uwe@fh-wedel.de)+ Stability : experimental+ Portability: portable++ Most of the XPath arrows come in two versions,+ one without dealing with namespaces, element and attribute names+ in XPath expressions are taken as they ar ignoring any prefix:localname structure.++ The second variant uses a namespace environment for associating the right+ namespace for the appropriate prefix. An entry for the empty prefix+ defines the default namespace for the expression.++ The second variant should be used, when in the application namespaces+ are significant, that means when namespace propagation is done for+ the documents to be processed.++ The XPath evaluator computes a result, which can be a simple value+ like a string or number, or a node set. The nodes in these sets+ are identified by their position in the document tree.+ Node sets are returned as a list of XmlTrees with respect to the+ document order.++-}++-- ------------------------------------------------------------++module Text.XML.HXT.XPath.Arrows+ ( getXPathTreesInDoc+ , getXPathTreesInDocWithNsEnv+ , getXPathTrees+ , getXPathTreesWithNsEnv+ , getElemNodeSet+ , getElemAndAttrNodeSet+ , getXPathNodeSet+ , getFromNodeSet+ , processXPathTrees+ , processXPathTreesWithNsEnv+ , processFromNodeSet+ )+where++import Control.Arrow.ListArrows++import Text.XML.HXT.XPath.XPathEval ( getXPathSubTreesWithNsEnv+ , getXPathNodeSetWithNsEnv'+ , addRoot'+ )+import Text.XML.HXT.DOM.Interface++import Text.XML.HXT.Arrow.XmlArrow+import Text.XML.HXT.Arrow.Edit ( canonicalizeForXPath )++-- ------------------------------------------------------------++-- |+-- Select parts of a whole XML document with root node by a XPath expression.+--+-- The main filter for selecting parts of a document via XPath.+--+-- The string argument must be a XPath expression with an absolute location path,+-- the argument tree must be a complete document tree.+--+-- Before evaluating the xpath query, the document is canonicalized+-- with 'Text.XML.HXT.Arrow.Edit.canonicalizeForXPath'+--+-- Result is a possibly empty list of XmlTrees forming the set of selected XPath values.+-- XPath values other than XmlTrees (numbers, attributes, tagnames, ...)+-- are convertet to text nodes.++getXPathTreesInDoc :: ArrowXml a => String -> a XmlTree XmlTree+getXPathTreesInDoc = getXPathTreesInDocWithNsEnv []++-- | Same as 'getXPathTreesInDoc' but with namespace environment for the XPath names++getXPathTreesInDocWithNsEnv :: ArrowXml a => Attributes -> String -> a XmlTree XmlTree+getXPathTreesInDocWithNsEnv env query = canonicalizeForXPath+ >>>+ arrL (getXPathSubTreesWithNsEnv env query)++-- |+-- Select parts of an arbitrary XML tree by a XPath expression.+--+-- The main filter for selecting parts of an arbitrary XML tree via XPath.+-- The string argument must be a XPath expression with an absolute location path,+-- There are no restrictions on the argument tree.+--+-- No canonicalization is performed before evaluating the query+--+-- Result is a possibly empty list of XmlTrees forming the set of selected XPath values.+-- XPath values other than XmlTrees (numbers, attributes, tagnames, ...)+-- are convertet to text nodes.++getXPathTrees :: ArrowXml a => String -> a XmlTree XmlTree+getXPathTrees = getXPathTreesWithNsEnv []++-- | Same as 'getXPathTrees' but with namespace environment for the XPath names++getXPathTreesWithNsEnv :: ArrowXml a => Attributes -> String -> a XmlTree XmlTree+getXPathTreesWithNsEnv env query = arrL (getXPathSubTreesWithNsEnv env query)++-- | Select a set of nodes via an XPath expression from an arbitray XML tree+--+-- The result is a set of \"pointers\" to nodes. This set can be used to+-- access or modify the values of the subnodes in subsequent calls to 'getFromNodeSet' or 'processFromNodeSet'.+--+-- This function enables for parsing an XPath expressions and traversing the tree for node selection once+-- and reuse this result possibly many times for later selection and modification operations.++getXPathNodeSet :: ArrowXml a => String -> a XmlTree XmlNodeSet+getXPathNodeSet = getXPathNodeSetWithNsEnv []++-- | Same as 'getXPathNodeSet' but with namespace environment for the XPath names++getXPathNodeSetWithNsEnv :: ArrowXml a => Attributes -> String -> a XmlTree XmlNodeSet+getXPathNodeSetWithNsEnv nsEnv query = arr (getXPathNodeSetWithNsEnv' nsEnv query)++-- ------------------------------------------------------------++getNodeSet :: ArrowXml a => a XmlTree QName -> a XmlTree XmlTree -> a XmlTree XmlNodeSet+getNodeSet af f = ( ( listA ( getChildren+ >>>+ getNodeSet af f+ )+ >>>+ arr filterNodeSet+ )+ &&&+ listA af+ &&&+ listA f+ )+ >>^ (\ ~(cl, (al, n)) -> XNS (not . null $ n) al cl)+ where+ filterNodeSet :: [XmlNodeSet] -> ChildNodes+ filterNodeSet = concat . zipWith filterIx [0..]++ filterIx :: Int -> XmlNodeSet -> ChildNodes+ filterIx _ix (XNS False [] []) = []+ filterIx ix ps = [(ix, ps)]++-- |+-- compute a node set from a tree, containing all nodes selected by the predicate arrow+--+-- computation of the set of element nodes with name \"a\" is done with+--+-- > getElemNodeSet (hasName "a")++getElemNodeSet :: ArrowXml a => a XmlTree XmlTree -> a XmlTree XmlNodeSet+getElemNodeSet f = getNodeSet none f++-- |+-- compute a node set from a tree, containing all nodes including attribute nodes+-- elected by the predicate arrow++getElemAndAttrNodeSet :: ArrowXml a => a XmlTree XmlTree -> a XmlTree XmlNodeSet+getElemAndAttrNodeSet f = getNodeSet ( getAttrl+ >>>+ ( f `guards` getAttrName )+ ) f++-- ------------------------------------------------------------++-- |+-- select all subtrees specified by a previously computed node set+--+-- the following law holds:+--+-- > getFromNodeSet $< getElemNodeSet f == multi f++getFromNodeSet :: ArrowXml a => XmlNodeSet -> a XmlTree XmlTree+getFromNodeSet xns = fromLA $+ arr addRoot' >>> getFromNodeSet' xns++getFromNodeSet' :: XmlNodeSet -> LA XmlTree XmlTree+getFromNodeSet' (XNS t al cl)+ = fromLA $+ ( if t then this else none )+ <+>+ ( getAttrl >>> getFromAttrl al )+ <+>+ ( getFromChildren (0-1) cl $< listA getChildren )+ where++ getFromAttrl :: [QName] -> LA XmlTree XmlTree+ getFromAttrl l+ = ( catA . map hasQName $ l)+ `guards`+ this++ getFromChildren :: Int -> ChildNodes -> XmlTrees -> LA XmlTree XmlTree+ getFromChildren _ [] _+ = none++ getFromChildren i' ((i, sp) : sps) ts+ = ( arrL (const t') >>> getFromNodeSet' sp )+ <+>+ getFromChildren i sps ts'+ where+ (t', ts') = splitAt 1 . drop (i-i'-1) $ ts++-- ------------------------------------------------------------++-- |+-- process all subtrees selected by an XPath expression+--+-- the following law holds:+--+-- > processXPathTrees p xpathExpr == processFromNodeSet p $< getXPathNodeSet xpathExpr++processXPathTrees :: ArrowXml a => a XmlTree XmlTree -> String -> a XmlTree XmlTree+processXPathTrees f = processXPathTreesWithNsEnv f []++-- | Same as 'processXPathTrees' but with namespace environment for the XPath names++processXPathTreesWithNsEnv :: ArrowXml a => a XmlTree XmlTree -> Attributes -> String -> a XmlTree XmlTree+processXPathTreesWithNsEnv f nsEnv query+ = choiceA+ [ isRoot :-> processChildren pns+ , this :-> pns+ ]+ where+ pns = processFromNodeSet f $< getXPathNodeSetWithNsEnv nsEnv query++-- ------------------------------------------------------------+-- |+-- process all subtrees specified by a previously computed node set in bottom up manner+--+-- the following law should hold:+--+-- > processFromNodeSet g $< getElemNodeSet f == processBottomUp (g `when` f)+--+-- when attributes are contained in the node set (see 'getElemAndAttrNodeSet'), these are processed+-- after the children and before the node itself+--+-- the advantage of processFromNodeSet is the separation of the selection of set of nodes to be processed (e.g. modified)+-- from the real proccessing. The selection sometimes can be done once, the processing possibly many times.++processFromNodeSet :: ArrowXml a => a XmlTree XmlTree -> XmlNodeSet -> a XmlTree XmlTree+processFromNodeSet f xns = ( isRoot+ `guards` processFromNodeSet' f xns+ )+ `orElse`+ ( arr addRoot'+ >>> processFromNodeSet' f xns+ >>> getChildren+ )+++processFromNodeSet' :: ArrowXml a => a XmlTree XmlTree -> XmlNodeSet -> a XmlTree XmlTree+processFromNodeSet' f (XNS t al cl)+ = ( if null cl+ then this+ else replaceChildren ( processC (0-1) cl $< listA getChildren )+ )+ >>>+ ( if null al+ then this+ else processAttrl (processA al)+ )+ >>>+ ( if not t+ then this+ else f+ )+ where++ -- processA :: ChildNodes -> a XmlTree XmlTree+ processA l+ = f `when` ( catA . map hasQName $ l)++ -- processC :: ChildNodes -> XmlTrees -> a XmlTree XmlTree+ processC _ [] ts+ = arrL (const ts)++ processC i' ((i, sp) : sps) ts+ = arrL (const ts1)+ <+>+ ( arrL (const ti) >>> processFromNodeSet' f sp)+ <+>+ processC i sps ts21+ where+ (ts1, ts2) = splitAt (i-i'-1) ts+ (ti, ts21) = splitAt 1 ts2++-- ------------------------------------------------------------
@@ -0,0 +1,194 @@+-- |+-- Navigable tree structure which allow a program to traverse+-- for XPath expressions+-- copied and modified from HXML (<http://www.flightlab.com/~joe/hxml/>)+--++module Text.XML.HXT.XPath.NavTree+ ( module Text.XML.HXT.XPath.NavTree+ , module Data.Tree.NTree.TypeDefs+ )+where++import Data.Maybe+import Data.Tree.NTree.TypeDefs++import Text.XML.HXT.DOM.Interface ( XNode+ , xmlnsNamespace+ , namespaceUri+ )+import Text.XML.HXT.DOM.XmlNode ( isRoot+ , isElem+ , getName+ , getAttrl+ )++-- -----------------------------------------------------------------------------++-- NavTree+--+-- | navigable tree with nodes of type node+--+-- a navigable tree consists of a n-ary tree for the current fragment tree,+-- a navigable tree for all ancestors, and two n-ary trees for+-- the previous- and following siblings++data NavTree a = NT { self :: (NTree a)+ , selfIndex :: Int+ , ancestors :: [NavTree a]+ , previousSiblings :: [NTree a]+ , followingSiblings :: [NTree a]+ }+ deriving (Show) -- deriving not reasonable for Eq and Ord++-- -----------------------------------------------------------------------------+++-- |+-- converts a n-ary tree in a navigable tree++ntree :: NTree a -> NavTree a+ntree nd = NT nd (-1) [] [] []++-- |+-- converts a navigable tree in a n-ary tree++subtreeNT :: NavTree a -> NTree a+subtreeNT (NT nd _ _ _ _) = nd+++-- |+-- function for selecting the value of the current fragment tree++dataNT :: NavTree a -> a+dataNT (NT (NTree a _) _ _ _ _) = a++-- |+-- function for selecting all children of a tree++childrenNT :: NavTree a -> [NTree a]+childrenNT (NT (NTree _ cs) _ _ _ _)+ = cs++-- |+-- position of tree in parent++indexNT :: NavTree a -> Int+indexNT (NT _ ix _ _ _) = ix++-- |+-- path (index list) of a navigatable tree++pathNT :: NavTree a -> [Int]+pathNT = tail . reverse . map selfIndex . ancestorOrSelfAxis++-- -----------------------------------------------------------------------------++-- functions for traversing up, down, left and right in a navigable tree++upNT+ , downNT+ , leftNT+ , rightNT :: NavTree a -> Maybe (NavTree a)++upNT (NT _ _ (p:_) _ _) = Just p+upNT (NT _ _ [] _ _) = Nothing+downNT t@(NT (NTree _ (c:cs)) _ u _ _) = Just (NT c 0 (t:u) [] cs)+downNT (NT (NTree _ [] ) _ _ _ _) = Nothing+leftNT (NT s ix u (l:ls) r) = Just (NT l (ix - 1) u ls (s:r))+leftNT (NT _ _ _ [] _) = Nothing+rightNT (NT s ix u l (r:rs)) = Just (NT r (ix + 1) u (s:l) rs)+rightNT (NT _ _ _ _ [] ) = Nothing+++-- preorderNT t = t : concatMap preorderNT (children t)+-- where children = maybe [] (maybeStar rightNT) . downNT++preorderNT :: NavTree a -> [NavTree a]+preorderNT = visit []+ where+ visit k t = t : maybe k (visit' k) (downNT t)+ visit' k t = visit (maybe k (visit' k) (rightNT t)) t++revPreorderNT :: NavTree a -> [NavTree a]+revPreorderNT t = t : concatMap revPreorderNT (reverse (children t))+ where+ children = maybe [] (maybeStar rightNT) . downNT++getChildrenNT :: NavTree a -> [NavTree a]+getChildrenNT node = maybe [] follow (downNT node)+ where+ follow n = n : maybe [] follow (rightNT n)++-- -----------------------------------------------------------------------------+-- Miscellaneous useful combinators++-- |+-- Kleisli composition:++o' :: (b -> [c]) -> (a -> [b]) -> (a -> [c])+f `o'` g = \x -> g x >>= f++-- Some useful anamorphisms:++maybeStar, maybePlus :: (a -> Maybe a) -> a -> [a]+maybeStar f a = a : maybe [] (maybeStar f) (f a)+maybePlus f a = maybe [] (maybeStar f) (f a)++-- -----------------------------------------------------------------------------+-- functions for representing XPath axes. All axes except the namespace-axis are supported+++parentAxis :: NavTree a -> [NavTree a]+parentAxis = maybeToList . upNT++ancestorAxis :: NavTree a -> [NavTree a]+ancestorAxis = ancestors -- or: maybePlus upNT++ancestorOrSelfAxis :: NavTree a -> [NavTree a]+ancestorOrSelfAxis t = t : ancestors t -- or: maybeStar upNT++childAxis :: NavTree a -> [NavTree a]+childAxis = maybe [] (maybeStar rightNT) . downNT++descendantAxis :: NavTree a -> [NavTree a]+descendantAxis = tail . preorderNT -- concatMap preorderNT . childAxis++descendantOrSelfAxis :: NavTree a -> [NavTree a]+descendantOrSelfAxis = preorderNT++followingSiblingAxis :: NavTree a -> [NavTree a]+followingSiblingAxis = maybePlus rightNT++precedingSiblingAxis :: NavTree a -> [NavTree a]+precedingSiblingAxis = maybePlus leftNT++selfAxis :: NavTree a -> [NavTree a]+selfAxis = (:[])++followingAxis :: NavTree a -> [NavTree a]+followingAxis = preorderNT `o'` followingSiblingAxis `o'` ancestorOrSelfAxis++precedingAxis :: NavTree a -> [NavTree a]+precedingAxis = revPreorderNT `o'` precedingSiblingAxis `o'` ancestorOrSelfAxis+++attributeAxis :: NavTree XNode -> [NavTree XNode]+attributeAxis t@(NT xt _ a _ _)+ | isElem xt+ &&+ not (isRoot xt) = foldr (\ (ix, attr) -> ((NT attr ix (t:a) [] []):)) [] al+ | otherwise = []+ where+ aix xs = zip [(0 - length xs) .. (-1)] xs+ al = filter ((/= xmlnsNamespace) . maybe "" namespaceUri . getName . snd)+ . aix+ . fromMaybe []+ . getAttrl $ xt++-- attributes are indexed in the path with negative indices+-- this corresponds to document order and makes the index paths+-- for attributes and children disjoint.+-- The attribute index is never referenced when navigating in trees++-- ------------------------------------------------------------
+ src/Text/XML/HXT/XPath/XPathArithmetic.hs view
@@ -0,0 +1,166 @@+-- |+-- The module contains arithmetic calculations according the IEEE 754 standard+-- for plus, minus, unary minus, multiplication, modulo and division.+--+++module Text.XML.HXT.XPath.XPathArithmetic+ ( xPathMulti+ , xPathMod+ , xPathDiv+ , xPathAdd+ , xPathUnary+ )+where++import Text.XML.HXT.XPath.XPathDataTypes+++-- |+-- Unary minus: the value 'NaN' is not calculatable and returned unchanged,+-- all other values can be denied.+--++xPathUnary :: XPathFilter+xPathUnary (XPVNumber (Float f)) = XPVNumber (Float (-f))+xPathUnary (XPVError e) = XPVError e+xPathUnary (XPVNumber NaN) = XPVNumber NaN+xPathUnary (XPVNumber Pos0) = XPVNumber Neg0+xPathUnary (XPVNumber Neg0) = XPVNumber Pos0+xPathUnary (XPVNumber PosInf) = XPVNumber NegInf+xPathUnary (XPVNumber NegInf) = XPVNumber PosInf+xPathUnary _ = XPVError "Call to unaryEval without a number"+++-- |+-- Multiplication+--++xPathMulti :: Op -> XPathValue -> XPathFilter+xPathMulti _ (XPVNumber (Float a)) (XPVNumber (Float b))+ = XPVNumber (Float (a * b))+xPathMulti _ (XPVNumber NegInf) (XPVNumber (Float a))+ | a < 0 = XPVNumber PosInf+ | otherwise = XPVNumber NegInf+xPathMulti _ (XPVNumber PosInf) (XPVNumber (Float a))+ | a < 0 = XPVNumber NegInf+ | otherwise = XPVNumber PosInf+xPathMulti _ (XPVNumber (Float a)) (XPVNumber NegInf)+ | a < 0 = XPVNumber PosInf+ | otherwise = XPVNumber NegInf+xPathMulti _ (XPVNumber (Float a)) (XPVNumber PosInf)+ | a < 0 = XPVNumber NegInf+ | otherwise = XPVNumber PosInf+xPathMulti _ (XPVNumber Pos0) (XPVNumber (Float a))+ | a < 0 = XPVNumber Neg0+ | otherwise = XPVNumber Pos0+xPathMulti _ (XPVNumber Neg0) (XPVNumber (Float a))+ | a < 0 = XPVNumber Pos0+ | otherwise = XPVNumber Neg0+xPathMulti _ (XPVNumber (Float a)) (XPVNumber Pos0)+ | a < 0 = XPVNumber Neg0+ | otherwise = XPVNumber Pos0+xPathMulti _ (XPVNumber (Float a)) (XPVNumber Neg0)+ | a < 0 = XPVNumber Pos0+ | otherwise = XPVNumber Neg0+xPathMulti a b c = xPathSpez a b c+++-- |+-- Modulo+--++xPathMod :: Op -> XPathValue -> XPathFilter+xPathMod _ (XPVNumber (Float a)) (XPVNumber (Float b))+ | floatMod a b == 0 = XPVNumber Pos0+ | otherwise = XPVNumber (Float (floatMod a b))+ where+ floatMod x y+ | x/y >= 0 = x - y * fromInteger(floor (x / y))+ | otherwise =x - y * fromInteger(ceiling (x / y))++xPathMod _ (XPVNumber (Float a)) (XPVNumber NegInf)+ = XPVNumber (Float a)+xPathMod _ (XPVNumber (Float a)) (XPVNumber PosInf)+ = XPVNumber (Float a)+xPathMod _ (XPVNumber Neg0) (XPVNumber Pos0)+ = XPVNumber Neg0+xPathMod a b c = xPathSpez a b c+++-- |+-- Division: the divison-operator is not according the IEEE 754 standard,+-- it calculates the same as the % operator in Java and ECMAScript+--++xPathDiv :: Op -> XPathValue -> XPathFilter+xPathDiv _ (XPVNumber (Float a)) (XPVNumber (Float b))+ = XPVNumber (Float (a / b))+xPathDiv _ (XPVNumber NegInf) (XPVNumber (Float a))+ | a < 0 = XPVNumber PosInf+ | otherwise = XPVNumber NegInf+xPathDiv _ (XPVNumber PosInf) (XPVNumber (Float a))+ | a < 0 = XPVNumber NegInf+ | otherwise = XPVNumber PosInf+xPathDiv _ (XPVNumber (Float a)) (XPVNumber NegInf)+ | a < 0 = XPVNumber Pos0+ | otherwise = XPVNumber Neg0+xPathDiv _ (XPVNumber (Float a)) (XPVNumber PosInf)+ | a < 0 = XPVNumber Neg0+ | otherwise = XPVNumber Pos0+xPathDiv _ (XPVNumber Neg0) (XPVNumber (Float a))+ | a < 0 = XPVNumber Pos0+ | otherwise = XPVNumber Neg0+xPathDiv _ (XPVNumber (Float a)) (XPVNumber Neg0)+ | a < 0 = XPVNumber PosInf+ | otherwise = XPVNumber NegInf+xPathDiv _ (XPVNumber (Float a)) (XPVNumber Pos0)+ | a < 0 = XPVNumber NegInf+ | otherwise = XPVNumber PosInf+xPathDiv a b c = xPathSpez a b c+++-- |+-- Plus and minus+--+-- 1.parameter op : plus or minus operation+--++xPathAdd :: Op -> XPathValue -> XPathFilter+xPathAdd Plus (XPVNumber (Float a)) (XPVNumber (Float b))+ = if a + b == 0+ then XPVNumber Pos0+ else XPVNumber (Float (a+b))+xPathAdd Minus (XPVNumber (Float a)) (XPVNumber (Float b))+ = if a - b == 0+ then XPVNumber Pos0+ else XPVNumber (Float (a-b))+xPathAdd _ (XPVNumber PosInf) (XPVNumber NegInf) = XPVNumber NaN+xPathAdd _ (XPVNumber NegInf) (XPVNumber PosInf) = XPVNumber NaN+xPathAdd _ (XPVNumber PosInf) _ = XPVNumber PosInf+xPathAdd _ (XPVNumber NegInf) _ = XPVNumber NegInf+xPathAdd _ _ (XPVNumber PosInf) = XPVNumber PosInf+xPathAdd _ _ (XPVNumber NegInf) = XPVNumber NegInf+xPathAdd _ (XPVNumber (Float a)) (XPVNumber Pos0) = XPVNumber (Float a)+xPathAdd op (XPVNumber Pos0) (XPVNumber (Float a))+ | op == Minus = XPVNumber (Float (-a))+ | otherwise = XPVNumber (Float a)+xPathAdd op (XPVNumber Neg0) (XPVNumber (Float a))+ | op == Minus = XPVNumber (Float (-a))+ | otherwise = XPVNumber (Float a)+xPathAdd _ (XPVNumber (Float a)) (XPVNumber Neg0) = XPVNumber (Float a)+xPathAdd _ (XPVNumber Neg0) (XPVNumber Pos0) = XPVNumber Neg0+xPathAdd _ (XPVNumber Pos0) (XPVNumber Neg0) = XPVNumber Neg0+xPathAdd _ (XPVNumber Neg0) (XPVNumber Neg0) = XPVNumber Neg0+xPathAdd _ (XPVNumber Pos0) (XPVNumber Pos0) = XPVNumber Pos0+xPathAdd a b c = xPathSpez a b c+++-- |+-- Identically results of the operators are combined to get+-- as few as possible combinations of the special IEEE values+--+xPathSpez :: Op -> XPathValue -> XPathFilter+xPathSpez _ (XPVError e) _ = XPVError e+xPathSpez _ _ (XPVError e) = XPVError e+xPathSpez _ _ _ = XPVNumber NaN
+ src/Text/XML/HXT/XPath/XPathDataTypes.hs view
@@ -0,0 +1,354 @@+-- ------------------------------------------------------------++{- |+ Module : Text.XML.HXT.XPath.XPathDataTypes+ Copyright : Copyright (C) 2006 Uwe Schmidt+ License : MIT++ Maintainer : Uwe Schmidt (uwe@fh-wedel.de)+ Stability : experimental+ Portability: portable++ The core data types of XPath.+ The Type NodeSet is based on the module "NavTree" which was adapted from+ HXML (<http://www.flightlab.com/~joe/hxml/>)++-}++-- ------------------------------------------------------------++module Text.XML.HXT.XPath.XPathDataTypes+ ( module Text.XML.HXT.XPath.XPathDataTypes+ , module Text.XML.HXT.XPath.NavTree+ )+where++import Data.Function ( on )+import Data.Map ( Map )+import qualified+ Data.Map as M++import Text.XML.HXT.XPath.NavTree+import Text.XML.HXT.DOM.Interface++-- -----------------------------------------------------------------------------+--+-- Expr++-- | Represents expression+-- ++data Expr = GenExpr Op [Expr] -- ^ generic expression with an operator and one or more operands+ | PathExpr (Maybe Expr) (Maybe LocationPath)+ -- ^ a path expression contains an optional filter-expression+ -- or an optional locationpath. one expression is urgently+ -- necessary, both are possible+ | FilterExpr [Expr] -- ^ filter-expression with zero or more predicates+ | VarExpr VarName -- ^ variable+ | LiteralExpr Literal -- ^ string+ | NumberExpr XPNumber -- ^ number+ | FctExpr FctName FctArguments -- ^ a function with a name and an optional list of arguments+ deriving (Show, Eq)+++-- -----------------------------------------------------------------------------+--+-- Op++-- | Represents XPath operators++data Op = Or | And | Eq | NEq | Less | Greater | LessEq+ | GreaterEq |Plus | Minus | Div | Mod | Mult| Unary | Union+ deriving (Show, Eq)+++-- -----------------------------------------------------------------------------+--+-- |+-- Represents a floating-point number according the IEEE 754 standard+--+-- The standard includes a special Not-a-Number (NaN) value,+-- positive and negative infinity, positive and negative zero.++data XPNumber = Float Float -- ^ floating-point number+ | NaN -- ^ not-a-number+ | NegInf -- ^ negative infinity+ | Neg0 -- ^ negative zero+ | Pos0 -- ^ positive zero+ | PosInf -- ^ positive infinity+++instance Show XPNumber+ where+ show NaN = "NaN"+ show NegInf = "-Infinity"+ show Neg0 = "-0"+ show Pos0 = "0"+ show (Float f) = show f+ show PosInf = "Infinity"++++-- Negative zero is equal to positive zero,+-- equality test with NaN-value is always false+instance Eq XPNumber+ where+ NegInf == NegInf = True+ Pos0 == Neg0 = True+ Neg0 == Pos0 = True+ Pos0 == Pos0 = True+ Neg0 == Neg0 = True+ Float f == Float g = f == g+ PosInf == PosInf = True+ _ == _ = False+++instance Ord XPNumber+ where+ a <= b = (a < b) || (a == b)+ a >= b = (a > b) || (a == b)+ a > b = b < a++ NaN < _ = False+ _ < NaN = False++ _ < NegInf = False+ NegInf < _ = True++ Neg0 < Neg0 = False+ Pos0 < Pos0 = False+ Pos0 < Neg0 = False+ Neg0 < Pos0 = False++ Neg0 < Float f = 0 < f+ Pos0 < Float f = 0 < f+ Float f < Neg0 = f < 0+ Float f < Pos0 = f < 0++ Float f < Float g = f < g++ PosInf < _ = False+ _ < PosInf = True+++-- -----------------------------------------------------------------------------+-- | Represents location path+--+-- A location path consists of a sequence of one or more location steps.++data LocationPath = LocPath Path [XStep]+ deriving (Show, Eq)+++-- ----------------------------------------------------------------------------- +-- |+-- A location path is either a relative or an absolute path.++data Path = Rel+ | Abs+ deriving (Show, Eq)+ ++-- | Represents location step+-- +-- A location step consists of an axis, a node-test and zero or more predicates.++data XStep = Step AxisSpec NodeTest [Expr]+ deriving (Show, Eq)++ +-- -----------------------------------------------------------------------------+--+-- AxisSpec++-- | Represents XPath axis++data AxisSpec = Ancestor+ | AncestorOrSelf+ | Attribute+ | Child+ | Descendant + | DescendantOrSelf+ | Following+ | FollowingSibling+ | Namespace+ | Parent+ | Preceding+ | PrecedingSibling+ | Self+ deriving (Show, Eq)++-- -----------------------------------------------------------------------------+--+-- NodeTest++-- | Represents XPath node-tests++--data NodeTest = NameTest Name -- ^ name-test+data NodeTest = NameTest QName -- ^ name-test+ | PI String -- ^ processing-instruction-test with a literal argument+ | TypeTest XPathNode -- ^ all nodetype-tests+ deriving (Show, Eq)++-- -----------------------------------------------------------------------------+--+-- XPathNode++-- | Represents nodetype-tests++data XPathNode = XPNode -- ^ all 7 nodetypes+ -- (root, element, attribute, namespace, pi, comment, text)+ | XPCommentNode -- ^ comment-nodes+ | XPPINode -- ^ processing-instruction-nodes+ | XPTextNode -- ^ text-nodes: cdata, character data+ deriving (Show, Eq)+++-- -----------------------------------------------------------------------------+--+-- useful type definitions++type Name = (NamePrefix, LocalName)+type NamePrefix = String+type LocalName = String++-- | Variable name+type VarName = Name++-- | a string+type Literal = String ++-- | Function name+type FctName = String++-- | Function arguments+type FctArguments = [Expr]++-- | Evaluation context+type Context = (ConPos ,ConLen, ConNode)++-- | Context position+type ConPos = Int++-- | Context length+type ConLen = Int++-- | Context node+type ConNode = NavXmlTree+++-- -----------------------------------------------------------------------------+--+-- XPathValue++-- | Represents XPath results++data XPathValue = XPVNode NodeSet -- ^ node-set+ | XPVBool Bool -- ^ boolean value+ | XPVNumber XPNumber -- ^ number according the IEEE 754 standard+ | XPVString String -- ^ string value+ | XPVError String -- ^ error message with text+ deriving (Show, Eq, Ord)++-- -----------------------------------------------------------------------------+--+-- Basic types for navigable tree and filters++-- | Node of navigable tree representation++type NavXmlTree = NavTree XNode++-- | List of nodes of navigable tree representation++type NavXmlTrees = [NavXmlTree]++-- | Set of navigable trees identified by their document position (NodePath)++newtype NodeSet = NS { unNS :: Map NodePath NavXmlTree }+ deriving (Show)++-- | path represented as list of indices starting at root++type NodePath = [Int]++-- | A functions that takes a XPath result and returns a XPath result++type XPathFilter = XPathValue -> XPathValue++-- -----------------------------------------------------------------------------++withXPVNode :: String -> (NodeSet -> XPathValue) -> XPathFilter+withXPVNode s f n = case n of+ XPVNode ns -> f ns+ e@(XPVError _) -> e+ _ -> XPVError s++-- -----------------------------------------------------------------------------++-- | node set functions++emptyNodeSet :: NodeSet+emptyNodeSet = NS M.empty++singletonNodeSet :: NavXmlTree -> NodeSet+singletonNodeSet = toNodeSet . (:[])++nullNodeSet :: NodeSet -> Bool+nullNodeSet = M.null . unNS++cardNodeSet :: NodeSet -> Int+cardNodeSet = M.size . unNS++deleteNodeSet :: NodePath -> NodeSet -> NodeSet+deleteNodeSet p = NS . M.delete p . unNS++insertNodeSet :: NavXmlTree -> NodeSet -> NodeSet+insertNodeSet t = NS . M.insert (pathNT t) t . unNS++unionNodeSet :: NodeSet -> NodeSet -> NodeSet+unionNodeSet ns1 = NS . M.union (unNS ns1) . unNS++unionsNodeSet :: [NodeSet] -> NodeSet+unionsNodeSet = NS . foldl (\ res ns -> M.union res $ unNS ns) M.empty++elemsNodeSet :: NodeSet -> [(NodePath, NavXmlTree)]+elemsNodeSet = M.toList . unNS++fromNodeSet :: NodeSet -> NavXmlTrees+fromNodeSet = M.elems . unNS++toNodeSet :: NavXmlTrees -> NodeSet+toNodeSet = NS . foldl (\ m t -> M.insert (pathNT t) t m) M.empty++headNodeSet :: NodeSet -> NavXmlTree+headNodeSet = head . fromNodeSet++withNodeSet :: (NavXmlTrees -> NavXmlTrees) -> NodeSet -> NodeSet+withNodeSet f = toNodeSet . f . fromNodeSet++instance Eq NodeSet where+ (==) = (==) `on` (M.keys . unNS)++instance Ord NodeSet where+ compare = compare `on` (M.keys . unNS)++-- -----------------------------------------------------------------------------+--+-- Env++-- | XPath environment+--+-- All variables are stored in the environment,+-- each variable name is bound to a value.++type VarTab = [(VarName, XPathValue)]+type KeyTab = [(QName, String, NavXmlTree)]++type Env = (VarTab, KeyTab)++varEnv :: Env+varEnv = ( [ (("", "name"), XPVNumber NaN) ]+ , []+ )++-- -----------------------------------------------------------------------------
+ src/Text/XML/HXT/XPath/XPathEval.hs view
@@ -0,0 +1,631 @@+-- ------------------------------------------------------------++{- |+ Module : Text.XML.HXT.XPath.XPathEval+ Copyright : Copyright (C) 2006 Uwe Schmidt+ License : MIT++ Maintainer : Uwe Schmidt (uwe@fh-wedel.de)+ Stability : experimental+ Portability: portable+ Version : $Id: XPathEval.hs,v 1.8 2006/10/12 11:51:29 hxml Exp $++ The core functions for evaluating the different types of XPath expressions.+ Each 'Expr'-constructor is mapped to an evaluation function.++-}++-- ------------------------------------------------------------++module Text.XML.HXT.XPath.XPathEval+ ( getXPath+ , getXPathWithNsEnv+ , getXPathSubTrees+ , getXPathSubTreesWithNsEnv+ , getXPathNodeSet'+ , getXPathNodeSetWithNsEnv'+ , evalExpr+ , addRoot'+ )+where++import Text.XML.HXT.XPath.XPathFct+import Text.XML.HXT.XPath.XPathDataTypes+import Text.XML.HXT.XPath.XPathArithmetic+ ( xPathAdd+ , xPathDiv+ , xPathMod+ , xPathMulti+ , xPathUnary+ )+import Text.XML.HXT.XPath.XPathParser ( parseXPath )+import Text.XML.HXT.XPath.XPathToString ( xPValue2XmlTrees )+import Text.XML.HXT.XPath.XPathToNodeSet( xPValue2XmlNodeSet+ , emptyXmlNodeSet+ )++import Text.ParserCombinators.Parsec ( runParser )++import Data.List ( partition )+import Data.Maybe ( fromJust, fromMaybe )++-- ----------------------------------------++-- the DOM functions++import Text.XML.HXT.DOM.Interface+import qualified Text.XML.HXT.DOM.XmlNode as XN++-- ----------------------------------------++-- the list arrow functions++import Control.Arrow ( (>>>), (>>^) )+import Control.Arrow.ArrowList ( arrL, isA )+import Control.Arrow.ArrowIf ( filterA )+import Control.Arrow.ListArrow ( runLA )+import qualified+ Control.Arrow.ArrowTree as AT++import Text.XML.HXT.Arrow.XmlArrow ( ArrowDTD, isDTD, getDTDAttrl )+import Text.XML.HXT.Arrow.Edit ( canonicalizeForXPath )++-- -----------------------------------------------------------------------------++-- |+-- Select parts of a document by an XPath expression.+--+-- The main filter for selecting parts of a document via XPath.+-- The string argument must be a XPath expression with an absolute location path,+-- the argument tree must be a complete document tree.+-- Result is a possibly empty list of XmlTrees forming the set of selected XPath values.+-- XPath values other than XmlTrees (numbers, attributes, tagnames, ...)+-- are convertet to text nodes.++getXPath :: String -> XmlTree -> XmlTrees+getXPath = getXPathWithNsEnv []++-- -----------------------------------------------------------------------------+-- |+-- Select parts of a document by a namespace aware XPath expression.+--+-- Works like 'getXPath' but the prefix:localpart names in the XPath expression+-- are interpreted with respect to the given namespace environment++getXPathWithNsEnv :: Attributes -> String -> XmlTree -> XmlTrees+getXPathWithNsEnv env s = runLA ( canonicalizeForXPath+ >>>+ arrL (getXPathValues xPValue2XmlTrees xPathErr (toNsEnv env) s)+ )++-- -----------------------------------------------------------------------------+-- |+-- Select parts of an XML tree by a XPath expression.+--+-- The main filter for selecting parts of an arbitrary XML tree via XPath.+-- The string argument must be a XPath expression with an absolute location path,+-- There are no restrictions on the arument tree.+--+-- No canonicalization is performed before evaluating the query+--+-- Result is a possibly empty list of XmlTrees forming the set of selected XPath values.+-- XPath values other than XmlTrees (numbers, attributes, tagnames, ...)+-- are convertet to text nodes.++getXPathSubTrees :: String -> XmlTree -> XmlTrees+getXPathSubTrees = getXPathSubTreesWithNsEnv []++-- -----------------------------------------------------------------------------+-- | Same as 'getXPathSubTrees' but with namespace aware XPath expression++getXPathSubTreesWithNsEnv :: Attributes -> String -> XmlTree -> XmlTrees+getXPathSubTreesWithNsEnv nsEnv xpStr+ = getXPathValues xPValue2XmlTrees xPathErr (toNsEnv nsEnv) xpStr++-- -----------------------------------------------------------------------------+-- | compute the node set of an XPath query++getXPathNodeSet' :: String -> XmlTree -> XmlNodeSet+getXPathNodeSet' = getXPathNodeSetWithNsEnv' []++-- -----------------------------------------------------------------------------+-- | compute the node set of a namespace aware XPath query++getXPathNodeSetWithNsEnv' :: Attributes -> String -> XmlTree -> XmlNodeSet+getXPathNodeSetWithNsEnv' nsEnv xpStr+ = getXPathValues xPValue2XmlNodeSet (const (const emptyXmlNodeSet)) (toNsEnv nsEnv) xpStr++-- -----------------------------------------------------------------------------++-- | parse xpath, evaluate xpath expr and prepare results++getXPathValues :: (XPathValue -> a) -> (String -> String -> a) -> NsEnv -> String -> XmlTree -> a+getXPathValues cvRes cvErr nsEnv xpStr t+ = case (runParser parseXPath nsEnv "" xpStr) of+ Left parseError -> cvErr xpStr (show parseError)+ Right xpExpr -> evalXP xpExpr+ where+ evalXP xpe = cvRes xpRes+ where+ t' = addRoot' t -- we need a root node for starting xpath eval+ idAttr = ( ("", "idAttr") -- id attributes from DTD (if there)+ , idAttributesToXPathValue . getIdAttributes $ t'+ )+ navTD = ntree t'+ xpRes = evalExpr (idAttr:(getVarTab varEnv),[]) (1, 1, navTD) xpe (XPVNode . singletonNodeSet $ navTD)++addRoot' :: XmlTree -> XmlTree+addRoot' t+ | XN.isRoot t = t+ | otherwise = XN.mkRoot [] [t]++xPathErr :: String -> String -> [XmlTree]+xPathErr xpStr parseError = [ XN.mkError c_err $+ ( "Syntax error in XPath expression " +++ show xpStr ++ ": " +++ show parseError+ )+ ]++-- -----------------------------------------------------------------------------++-- |+-- The main evaluation entry point. +-- Each XPath-'Expr' is mapped to an evaluation function. The 'Env'-parameter contains the set of global variables+-- for the evaluator, the 'Context'-parameter the root of the tree in which the expression is evaluated.+-- ++evalExpr :: Env -> Context -> Expr -> XPathFilter+evalExpr env cont (GenExpr Or ex) = boolEval env cont Or ex+evalExpr env cont (GenExpr And ex) = boolEval env cont And ex+evalExpr env cont (GenExpr Eq ex) = relEqEval env cont Eq . evalExprL env cont ex+evalExpr env cont (GenExpr NEq ex) = relEqEval env cont NEq . evalExprL env cont ex+evalExpr env cont (GenExpr Less ex) = relEqEval env cont Less . evalExprL env cont ex+evalExpr env cont (GenExpr LessEq ex) = relEqEval env cont LessEq . evalExprL env cont ex+evalExpr env cont (GenExpr Greater ex) = relEqEval env cont Greater . evalExprL env cont ex+evalExpr env cont (GenExpr GreaterEq ex)+ = relEqEval env cont GreaterEq . evalExprL env cont ex+evalExpr env cont (GenExpr Plus ex) = numEval xPathAdd Plus . toXValue xnumber cont env . evalExprL env cont ex+evalExpr env cont (GenExpr Minus ex) = numEval xPathAdd Minus . toXValue xnumber cont env . evalExprL env cont ex+evalExpr env cont (GenExpr Div ex) = numEval xPathDiv Div . toXValue xnumber cont env . evalExprL env cont ex+evalExpr env cont (GenExpr Mod ex) = numEval xPathMod Mod . toXValue xnumber cont env . evalExprL env cont ex+evalExpr env cont (GenExpr Mult ex) = numEval xPathMulti Mult . toXValue xnumber cont env . evalExprL env cont ex+evalExpr env cont (GenExpr Unary ex) = xPathUnary . xnumber cont env . evalExprL env cont ex+evalExpr env cont (GenExpr Union ex) = unionEval . evalExprL env cont ex+evalExpr env cont (FctExpr name args) = fctEval env cont name args++evalExpr env _ (PathExpr Nothing (Just lp))+ = locPathEval env lp+evalExpr env cont (PathExpr (Just fe) (Just lp))+ = locPathEval env lp . evalExpr env cont fe++evalExpr env cont (FilterExpr ex) = filterEval env cont ex+evalExpr env _ ex = evalSpezExpr env ex++-- -----------------------------------------------------------------------------++evalExprL :: Env -> Context -> [Expr] -> XPathValue -> [XPathValue]+evalExprL env cont ex ns = map (\e -> evalExpr env cont e ns) ex++-- -----------------------------------------------------------------------------++evalSpezExpr :: Env -> Expr -> XPathFilter+evalSpezExpr _ (NumberExpr (Float 0)) _ = XPVNumber Pos0+evalSpezExpr _ (NumberExpr (Float f)) _ = XPVNumber (Float f)+evalSpezExpr _ (LiteralExpr s) _ = XPVString s+evalSpezExpr env (VarExpr name) v = getVariable env name v+evalSpezExpr _ _ _ = XPVError "Call to evalExpr with a wrong argument"++-- -----------------------------------------------------------------------------++-- |+-- filter for evaluating a filter-expression++filterEval :: Env -> Context -> [Expr] -> XPathFilter+filterEval env cont (prim:predicates) ns+ = case evalExpr env cont prim ns of+ new_ns@(XPVNode _) -> evalPredL env predicates new_ns+ _ -> XPVError "Return of a filterexpression is not a nodeset"+filterEval _ _ _ _ = XPVError "Call to filterEval without an expression"+++-- -----------------------------------------------------------------------------+-- |+-- returns the union of its arguments, the arguments have to be node-sets.++unionEval :: [XPathValue] -> XPathValue+unionEval vs+ | not (null evs) = case head evs of+ e@(XPVError _) -> e+ _ -> XPVError "A value of a union ( | ) is not a nodeset"+ | otherwise = XPVNode . unionsNodeSet . map theNode $ nvs+ where+ (nvs, evs) = partition isNode vs++ isNode (XPVNode _) = True+ isNode _ = False++ theNode (XPVNode ns) = ns+ theNode _ = error "illegal argument in unionEval"++-- -----------------------------------------------------------------------------+-- |+-- Equality or relational test for node-sets, numbers, boolean values or strings,+-- each computation of two operands is done by relEqEv'++relEqEval :: Env -> Context -> Op -> [XPathValue] -> XPathValue+relEqEval env cont op = foldl1 (relEqEv' env cont op) ++relEqEv' :: Env -> Context -> Op -> XPathValue -> XPathFilter+relEqEv' _ _ _ e@(XPVError _) _ = e+relEqEv' _ _ _ _ e@(XPVError _) = e++-- two node-sets++relEqEv' env cont op a@(XPVNode _)+ b@(XPVNode _) = relEqTwoNodes env cont op a b++-- one node-set++relEqEv' env cont op a b@(XPVNode _) = relEqOneNode env cont (fromJust $ getOpFct op) a b+relEqEv' env cont op a@(XPVNode _) b = relEqOneNode env cont (flip $ fromJust $ getOpFct op) b a+++-- test without a node-set and equality or not-equality operator++relEqEv' env cont Eq a b = eqEv env cont (==) a b+relEqEv' env cont NEq a b = eqEv env cont (/=) a b++-- test without a node-set and less, less-equal, greater or greater-equal operator++relEqEv' env cont op a b = XPVBool ((fromJust $ getOpFct op) (toXNumber a) (toXNumber b))+ where+ toXNumber x = xnumber cont env [x]++-- -----------------------------------------------------------------------------++-- |+-- Equality or relational test for two node-sets.+-- The comparison will be true if and only if there is a node in the first node-set+-- and a node in the second node-set such that the result of performing the+-- comparison on the string-values of the two nodes is true++relEqTwoNodes :: Env -> Context -> Op -> XPathValue -> XPathFilter+relEqTwoNodes _ _ op (XPVNode ns)+ (XPVNode ms) = XPVBool $+ foldr (\n -> (any (fct op n) (getStrValues ms) ||)) False $+ fromNodeSet ns+ where+ fct op' n' = (fromJust $ getOpFct op') (stringValue n')+ getStrValues = map stringValue . fromNodeSet+relEqTwoNodes _ _ _ _ _ = XPVError "Call to relEqTwoNodes without a nodeset"++-- -----------------------------------------------------------------------------+-- |+-- Comparison between a node-set and different type.+-- The node-set is converted in a boolean value if the second argument is of type boolean.+-- If the argument is of type number, the node-set is converted in a number, otherwise it is converted+-- in a string value.++relEqOneNode :: Env -> Context ->+ (XPathValue -> XPathValue -> Bool) -> XPathValue -> XPathFilter++relEqOneNode env cont fct arg = withXPVNode "Call to relEqOneNode without a nodeset" $+ \ ns -> XPVBool (any (fct arg) (getStrValues arg ns))+ where+ getStrValues arg' = map ((fromJust $ getConvFct arg') cont env . (:[])) .+ map stringValue .+ fromNodeSet++-- -----------------------------------------------------------------------------++-- |+-- No node-set is involved and the operator is equality or not-equality.+-- The arguments are converted in a common type. If one argument is a boolean value+-- then it is the boolean type. If a number is involved, the arguments have to converted in numbers,+-- else the string type is the common type.++eqEv :: Env -> Context -> (XPathValue -> XPathValue -> Bool) -> XPathValue -> XPathFilter+eqEv env cont fct f@(XPVBool _) g = XPVBool (f `fct` xboolean cont env [g])+eqEv env cont fct f g@(XPVBool _) = XPVBool (xboolean cont env [f] `fct` g)+eqEv env cont fct f@(XPVNumber _) g = XPVBool (f `fct` xnumber cont env [g])+eqEv env cont fct f g@(XPVNumber _) = XPVBool (xnumber cont env [f] `fct` g)+eqEv env cont fct f g = XPVBool (xstring cont env [f] `fct` xstring cont env [g])++-- -----------------------------------------------------------------------------++getOpFct :: Op -> Maybe (XPathValue -> XPathValue -> Bool)+getOpFct Eq = Just (==)+getOpFct NEq = Just (/=)+getOpFct Less = Just (<)+getOpFct LessEq = Just (<=)+getOpFct Greater = Just (>)+getOpFct GreaterEq = Just (>=)+getOpFct _ = Nothing++-- -----------------------------------------------------------------------------++-- |+-- Filter for accessing the root element of a document tree++getRoot :: XPathFilter+getRoot = withXPVNode "Call to getRoot without a nodeset" $ getRoot'+ where+ getRoot' ns+ | nullNodeSet ns = XPVError "Call to getRoot with empty nodeset"+ | otherwise = XPVNode . singletonNodeSet . getRoot'' . headNodeSet $ ns++ getRoot'' tree = case upNT tree of+ Nothing -> tree+ Just t -> getRoot'' t++-- -----------------------------------------------------------------------------++-- |+-- Filter for accessing all nodes of a XPath-axis+--+-- * 1.parameter as : axis specifier+--+getAxisNodes :: AxisSpec -> XPathFilter+getAxisNodes as = withXPVNode "Call to getAxis without a nodeset" evalAxis+ where+ evalAxis = XPVNode .+ withNodeSet (concatMap (fromJust $ lookup as axisFctL))++-- |+-- Axis-Function-Table.+-- Each XPath axis-specifier is mapped to the corresponding axis-function++axisFctL :: [(AxisSpec, (NavXmlTree -> NavXmlTrees))]+axisFctL = [ (Ancestor , ancestorAxis)+ , (AncestorOrSelf , ancestorOrSelfAxis)+ , (Attribute , attributeAxis)+ , (Child , childAxis)+ , (Descendant , descendantAxis)+ , (DescendantOrSelf , descendantOrSelfAxis)+ , (Following , followingAxis)+ , (FollowingSibling , followingSiblingAxis)+ , (Parent , parentAxis)+ , (Preceding , precedingAxis)+ , (PrecedingSibling , precedingSiblingAxis)+ , (Self , selfAxis)+ ]++-- -----------------------------------------------------------------------------+-- |+-- evaluates a location path,+-- evaluation of an absolute path starts at the document root, +-- the relative path at the context node++locPathEval :: Env -> LocationPath -> XPathFilter+locPathEval env (LocPath Rel steps) = evalSteps env steps+locPathEval env (LocPath Abs steps) = evalSteps env steps . getRoot+++-- -----------------------------------------------------------------------------++evalSteps :: Env -> [XStep] -> XPathFilter+evalSteps env steps ns = foldl (evalStep env) ns steps++-- |+-- evaluate a single XPath step+-- namespace-axis is not supported++evalStep :: Env -> XPathValue -> XStep -> XPathValue++evalStep _ _ (Step Namespace _ _) = XPVError "namespace-axis not supported"+evalStep _ ns (Step Attribute nt _) = evalAttr nt (getAxisNodes Attribute ns)+evalStep env ns (Step axisSpec nt pr) = evalStep' env pr nt (getAxisNodes axisSpec ns)++-- -----------------------------------------------------------------------------++evalAttr :: NodeTest -> XPathFilter+evalAttr nt = withXPVNode "Call to evalAttr without a nodeset" $+ evalTest+ where+ evalTest = XPVNode .+ withNodeSet (concatMap . evalAttrNodeTest $ nt)++evalAttrNodeTest :: NodeTest -> NavXmlTree -> NavXmlTrees+evalAttrNodeTest (NameTest qn)+ ns@(NT (NTree (XAttr qn1) _) _ix _ _ _)+ = if ( ( uri == uri1 && lp == lp1)+ || + ((uri == "" || uri == uri1) && lp == "*") + )+ then [ns]+ else []+ where+ uri = namespaceUri qn+ uri1 = namespaceUri qn1+ lp = localPart qn+ lp1 = localPart qn1++evalAttrNodeTest (TypeTest XPNode)+ ns@(NT (NTree (XAttr _) _) _ix _ _ _)+ = [ns]+evalAttrNodeTest _ _ = []++evalStep' :: Env -> [Expr] -> NodeTest -> XPathFilter+evalStep' env pr nt = evalPredL env pr . nodeTest nt++-- -----------------------------------------------------------------------------++evalPredL :: Env -> [Expr] -> XPathFilter+evalPredL env pr n = withXPVNode "Call to evalPredL without a nodeset" evalPl n+ where+ evalPl ns = foldl (evalPred env 1 (cardNodeSet ns)) n pr++evalPred :: Env -> Int -> Int -> XPathValue -> Expr -> XPathValue+evalPred env pos len nv@(XPVNode ns) ex+ | nullNodeSet ns = nv+ | otherwise = case testPredicate env (pos, len, x) ex (XPVNode . singletonNodeSet $ x) of+ e@(XPVError _) -> e+ XPVBool True -> XPVNode $ insertNodeSet x n+ XPVBool False -> nextNode+ _ -> XPVError "Value of testPredicate is not a boolean"+ where+ (xp, x) = head . elemsNodeSet $ ns+ xs = deleteNodeSet xp ns+ nextNode@(XPVNode n) = evalPred env (pos + 1) len (XPVNode xs) ex+evalPred _ _ _ _ _ = XPVError "Call to evalPred without a nodeset"+++testPredicate :: Env -> Context -> Expr -> XPathFilter+testPredicate env context@(pos, _, _) ex ns = case evalExpr env context ex ns of+ XPVNumber (Float f) -> XPVBool (f == fromIntegral pos)+ XPVNumber _ -> XPVBool False+ _ -> xboolean context env [evalExpr env context ex ns]++-- -----------------------------------------------------------------------------+-- |+-- filter for selecting a special type of nodes from the current fragment tree+--+-- the filter works with namespace activated and without namespaces.+-- If namespaces occur in XPath names, the uris are used for matching,+-- else the name prefix+--+-- Bugfix : "*" (or any other name-test) must not match the root node++nodeTest :: NodeTest -> XPathFilter++-- nodeTest (NameTest (QN "" "*" "")) = filterNodes (\n -> isXTagNode n && not (isRootNode n))+-- nodeTest (NameTest (QN _ "*" uri)) = filterNodes (filterd uri)++nodeTest (NameTest q)+ | isWildcardTest = filterNodes (wildcardTest q)+ | otherwise = filterNodes (nameTest q) -- old: (isOfTagNode1 q)+ where+ isWildcardTest = localPart q == "*"++nodeTest (PI n) = filterNodes isPiNode+ where+ isPiNode = maybe False ((== n) . qualifiedName) . XN.getPiName++nodeTest (TypeTest t) = typeTest t++-- -----------------------------------------------------------------------------++nameTest :: QName -> XNode -> Bool+nameTest xpName (XTag elemName _)+ | namespaceAware = localPart xpName == localPart elemName+ &&+ namespaceUri xpName == namespaceUri elemName+ | otherwise = qualifiedName xpName == qualifiedName elemName+ where+ namespaceAware = not . null . namespaceUri $ xpName++nameTest _ _ = False++-- -----------------------------------------------------------------------------++wildcardTest :: QName -> XNode -> Bool+wildcardTest xpName (XTag elemName _)+ | namespaceAware = namespaceUri xpName == namespaceUri elemName+ | prefixMatch = namePrefix xpName == namePrefix elemName+ | otherwise = localPart elemName /= t_root -- all names except the root name "/"+ where+ namespaceAware = not . null . namespaceUri $ xpName+ prefixMatch = not . null . namePrefix $ xpName++wildcardTest _ _ = False++-- -----------------------------------------------------------------------------+-- |+-- tests whether a node is of a special type+--+typeTest :: XPathNode -> XPathFilter+typeTest XPNode = id+typeTest XPCommentNode = filterNodes XN.isCmt+typeTest XPPINode = filterNodes XN.isPi+typeTest XPTextNode = filterNodes XN.isText++-- -----------------------------------------------------------------------------+-- |+-- the filter selects the NTree part of a navigable tree and+-- tests whether the node is of the necessary type+--+-- * 1.parameter fct : filter function from the XmlTreeFilter module which tests the type of a node++filterNodes :: (XNode -> Bool) -> XPathFilter+filterNodes fct = withXPVNode "Call to filterNodes without a nodeset" $+ (XPVNode . withNodeSet (filter (fct . dataNT)))++-- -----------------------------------------------------------------------------+-- |+-- evaluates a boolean expression, the evaluation is non-strict++boolEval :: Env -> Context -> Op -> [Expr] -> XPathFilter+boolEval _ _ op [] _ = XPVBool (op == And)+boolEval env cont Or (x:xs) ns = case xboolean cont env [evalExpr env cont x ns] of+ e@(XPVError _) -> e+ XPVBool True -> XPVBool True+ _ -> boolEval env cont Or xs ns++boolEval env cont And (x:xs) ns = case xboolean cont env [evalExpr env cont x ns] of+ e@(XPVError _) -> e+ XPVBool True -> boolEval env cont And xs ns+ _ -> XPVBool False+boolEval _ _ _ _ _ = XPVError "Call to boolEval with a wrong argument"+++-- -----------------------------------------------------------------------------+-- |+-- returns the value of a variable+getVariable :: Env -> VarName -> XPathFilter+getVariable env name _ = fromMaybe (XPVError ("Variable: " ++ show name ++ " not found")) $+ lookup name (getVarTab env)+++-- -----------------------------------------------------------------------------+-- |+-- evaluates a function, +-- computation is done by 'XPathFct.evalFct' which is defined in "XPathFct".++fctEval :: Env -> Context -> FctName -> [Expr] -> XPathFilter+fctEval env cont name args = evalFct name env cont . evalExprL env cont args++-- -----------------------------------------------------------------------------+-- |+-- evaluates an arithmetic operation.+--+-- 1.parameter f : arithmetic function from "XPathArithmetic"+--+numEval :: (Op -> XPathValue -> XPathValue -> XPathValue) ->+ Op -> [XPathValue] -> XPathValue+numEval f op = foldl1 (f op)++-- -----------------------------------------------------------------------------+-- |+-- Convert list of ID attributes from DTD into a space separated 'XPVString'+--++idAttributesToXPathValue :: XmlTrees -> XPathValue+idAttributesToXPathValue ts = XPVString (foldr (\ n -> ( (valueOfDTD a_value n ++ " ") ++)) [] ts)++-- -----------------------------------------------------------------------------+-- |+-- Extracts all ID-attributes from the document type definition (DTD).+--++getIdAttributes :: XmlTree -> XmlTrees+getIdAttributes = runLA $+ AT.getChildren+ >>>+ isDTD+ >>>+ AT.deep (isIdAttrType)++-- ----------------------------------------++isIdAttrType :: ArrowDTD a => a XmlTree XmlTree+isIdAttrType = hasDTDAttrValue a_type (== k_id)++valueOfDTD :: String -> XmlTree -> String+valueOfDTD n = concat . runLA ( getDTDAttrl >>^ lookup1 n )++hasDTDAttrValue :: ArrowDTD a => String -> (String -> Bool) -> a XmlTree XmlTree+hasDTDAttrValue an p = filterA $+ getDTDAttrl >>> isA (p . lookup1 an)++-- ------------------------------------------------------------
+ src/Text/XML/HXT/XPath/XPathFct.hs view
@@ -0,0 +1,864 @@+-- ------------------------------------------------------------++{- |+ Module : Text.XML.HXT.XPath.XPathFct+ Copyright : Copyright (C) 2008 Uwe Schmidt+ License : MIT++ Maintainer : Uwe Schmidt (uwe@fh-wedel.de)+ Stability : experimental+ Portability: portable++ The module contains the core-functions of the XPath function library.+ All functions are implemented as XFct. Each XFct contains the evaluation context,+ the variable environment and the function arguments.++-}++-- ------------------------------------------------------------++module Text.XML.HXT.XPath.XPathFct+ ( XFct+ , evalFct+ , toXValue+ , xnumber+ , xboolean+ , xstring+ , getConvFct+ , stringValue+-- , remDups+ , isNotInNodeList+{-+ , createDocumentOrder+ , createDocumentOrderReverse+-}+ , getVarTab+ , getKeyTab+ )+where++import Text.XML.HXT.XPath.XPathDataTypes+import Text.XML.HXT.XPath.XPathParser+ ( parseNumber+ )+import Text.XML.HXT.XPath.XPathArithmetic+ ( xPathAdd+ )++import Control.Arrow ( (>>>), (<+>) )+import Control.Arrow.ArrowList ( constA )+import Control.Arrow.ArrowIf ( ifA )+import Control.Arrow.ArrowTree ( deep )+import Control.Arrow.ListArrow ( LA, runLA )++import Text.XML.HXT.Arrow.XmlArrow+import Text.XML.HXT.Arrow.ReadDocument (readDocument)+import Text.XML.HXT.Arrow.XmlIOStateArrow (runX)++import Text.XML.HXT.DOM.Interface+import qualified Text.XML.HXT.DOM.XmlNode as XN++import System.IO.Unsafe ( unsafePerformIO+ )++import Data.Char ( isAscii+ , isUpper+ , isLower+ , isDigit+ , ord+ )++import Data.Maybe++-- -----------------------------------------------------------------------------++-- added by Tim Walkenhorst to fix Pos0 vs. Float 0.0 problems...++int2XPNumber :: Int -> XPNumber+int2XPNumber 0 = Pos0+int2XPNumber i = Float $ fromIntegral i++-- |+-- Type signature for all functions which can be used in the XPath module.++type XFct = (Context -> Env -> [XPathValue] -> XPathValue)++-- |+-- All functions are stored in a function table.++type FctTable = [(FctName, FctTableElem)]++-- |+-- Each table entry consists of the function and the expected function arguments.++type FctTableElem = (XFct, CheckArgCount)++-- |+-- Tests whether the number of current function arguments is correct++type CheckArgCount = ([XPathValue] -> Bool)++-- -----------------------------------------------------------------------------++zero+ , zeroOrOne+ , one+ , two+ , twoOrM+ , twoOrThree+ , three :: CheckArgCount++zero ex = length ex == 0+zeroOrOne ex = length ex == 0 || length ex == 1+one ex = length ex == 1+two ex = length ex == 2+twoOrM ex = length ex >= 2+twoOrThree ex = length ex == 2 || length ex == 3+three ex = length ex == 3+++-- -----------------------------------------------------------------------------+-- |+-- The core-functions library++fctTable :: FctTable+fctTable = [+ ("last", (xlast, zero)), -- nodeset functions+ ("position",(xposition, zero)),+ ("count",(xcount, one)),+ ("id", (xid, one)),+ ("local-name", (xlocalName, zeroOrOne)),+ ("namespace-uri", (xnamespaceUri, zeroOrOne)),+ ("name", (xname, zeroOrOne)),++ ("string", (xstring, zeroOrOne)), -- string functions+ ("concat", (xconcat, twoOrM)),+ ("starts-with",(xstartsWith, two)),+ ("contains", (xcontains, two)),+ ("substring-before", (xsubstringBefore, two)),+ ("substring-after", (xsubstringAfter, two)),+ ("substring", (xsubstring, twoOrThree)),+ ("string-length", (xstringLength, zeroOrOne)),+ ("normalize-space", (xnormalizeSpace, zeroOrOne)),+ ("translate", (xtranslate, three)),++ ("boolean", (xboolean, one)), -- boolean functions+ ("not", (xnot, one)),+ ("true", (xtrue, zero)),+ ("false",(xfalse, zero)),+ ("lang", (xlang, one)),++ ("number",(xnumber, zeroOrOne)), -- number functions+ ("sum",(xsum, one)),+ ("floor",(xfloor, one)),+ ("ceiling",(xceiling, one)),+ ("round",(xround, one)),+ ("key",(xkey, two)),+ ("format-number",(xformatNumber, twoOrThree)),+ + ("document", (xdocument, one)),-- extension functions for xslt 1.0+ ("generate-id", (xgenerateId, zeroOrOne))+ + ]++-- -----------------------------------------------------------------------------++-- some helper functions++-- |+-- Returns the table of keys, needed by xslt, from the environment++getKeyTab :: Env -> KeyTab+getKeyTab (_, keyTab) = keyTab+++-- -----------------------------------------------------------------------------+-- |+-- Returns the table of variables from the environment++getVarTab :: Env -> VarTab+getVarTab (varTab, _) = varTab+++-- -----------------------------------------------------------------------------+-- |+-- Returns the conversion function for the XPath results: string, boolean and number+-- A nodeset can not be converted.++getConvFct :: XPathValue -> Maybe XFct+getConvFct (XPVNumber _) = Just xnumber+getConvFct (XPVString _) = Just xstring+getConvFct (XPVBool _) = Just xboolean+getConvFct _ = Nothing++-- -----------------------------------------------------------------------------+-- |+-- Check whether a node is not a part of a node list. Needed to implement matching & testing in xslt.++isNotInNodeList :: NavXmlTree -> [NavXmlTree] -> Bool+isNotInNodeList n xs' = nodeID' n `notElem` map nodeID' xs'++-- -----------------------------------------------------------------------------+-- |+-- calculate an ID for a NODE+--+-- - returns : a list of numbers, one number for each level of the tree++-- Tim Walkenhorst:+-- - Attributes are identified by their QName (they do not have previous siblings)+-- - Elements are identified by their relative position (# of previous siblings)++data IdPathStep = IdRoot String+ | IdPos Int+ | IdAttr QName+ deriving (Show, Eq, Ord)++nodeID :: Maybe NavXmlTree -> [IdPathStep]+nodeID = maybe [] nodeID'++nodeID' :: NavXmlTree -> [IdPathStep]+nodeID' t@(NT (NTree (XAttr qn) _) _ix _ _ _)+ = IdAttr qn : nodeID (upNT t)++nodeID' t@(NT node ix _ _ _)+ | XN.isRoot node = return $ IdRoot (getRootId node) + | otherwise = IdPos ix : nodeID (upNT t)+ where+ getRootId = concat . runLA (getAttrValue "rootId")++-- -----------------------------------------------------------------------------+-- |+-- Evaluates a function.+-- Calculation of the function value is done by looking up the function name in the function table,+-- check the number of arguments and calculate the funtion, if no+-- argument evaluation returns an error.+--+-- - returns : the function value as 'XPathValue'++evalFct :: FctName -> Env -> Context -> [XPathValue] -> XPathValue+evalFct name env cont args+ = case (lookup name fctTable) of+ Nothing -> XPVError ("Call to undefined function "++ name)+ Just (fct, checkArgCount) ->+ if not (checkArgCount args)+ then XPVError ("Call to function "++ name ++ " with wrong arguments")+ else case (checkArgErrors args) of+ Just e -> e+ Nothing -> fct cont env args+ where+ checkArgErrors [] = Nothing+ checkArgErrors ((XPVError r):_) = Just (XPVError r)+ checkArgErrors (_:xs) = checkArgErrors xs+++-- |+-- Converts a list of different 'XPathValue' types in a list of one 'XPathValue' type.+--+-- * 1.parameter fct : the conversion function+--++toXValue :: XFct -> Context -> Env -> [XPathValue] -> [XPathValue]+toXValue fct c env args = [fct c env [x] | x <- args]++-- -----------------------------------------------------------------------------+-- core-funktions library++-- nodeset functions++-- |+-- number last(): returns a number equal to the context size from the expression evaluation context++xlast :: XFct+xlast (_, len , _) _ _ = XPVNumber $ int2XPNumber len+++-- -----------------------------------------------------------------------------+-- |+-- number position(): returns a number equal to the context position from the expression evaluation context++xposition :: XFct+xposition (pos, _ , _) _ _ = XPVNumber $ int2XPNumber pos+++-- -----------------------------------------------------------------------------+-- |+-- number count(node-set): returns the number of nodes in the argument node-set++xcount :: XFct+xcount _ _ [XPVNode ns] = XPVNumber . int2XPNumber . cardNodeSet $ ns+xcount _ _ _ = XPVError "Call to function count with wrong arguments"+++-- -----------------------------------------------------------------------------+-- |+-- node-set id(object): selects elements by their unique ID++xid :: XFct+xid (_, _, cn) env [XPVNode ns] = isInId (getIds env) (strValues ns) [cn]+ where+ strValues = map ((\ (XPVString str) -> str) . stringValue) . fromNodeSet++xid c@(_, _, cn) env arg = isInId (getIds env) ( (\(XPVString s) -> words s) (xstring c env arg)) [cn]++++-- -----------------------------------------------------------------------------+-- |+-- returns all IDs from the variable environment as a list of strings.+-- the IDs are stored in the variable: idAttr++getIds :: Env -> [String]+getIds env = words $ -- hier muss noch auf prefix getestet werden+ (\ (XPVString str) -> str) . fromJust $ lookup ("", "idAttr") $+ getVarTab env ++-- -----------------------------------------------------------------------------++isInId :: [String] -> [String] -> NavXmlTrees -> XPathValue+isInId ids str = XPVNode . toNodeSet . concatMap (filterNS ids str . descendantOrSelfAxis)+++-- -----------------------------------------------------------------------------++filterNS :: [String] -> [String] -> NavXmlTrees -> NavXmlTrees+filterNS ids str ns = [ n | n@(NT a _ _ _ _) <- ns+ , or $ map (idInIdList a str) ids+ ]+ where+ idInIdList :: XmlTree -> [String] -> String -> Bool+ idInIdList al str' b = (getValue b al) `elem` str'+++-- -----------------------------------------------------------------------------+-- |+-- string local-name(node-set?):+-- returns the local part of the expanded-name of the node in the argument node-set+-- that is first in document order. +-- If the argument node-set is empty or the first node has no expanded-name, an empty string is returned. +-- If the argument is omitted, it defaults to a node-set with the context node as its only member++-- Bugfix: name(\/) is "" not "\/"!++xlocalName :: XFct+xlocalName (_, _, cn) _ [] = XPVString (xpLocalPartOf . subtreeNT $ cn)+xlocalName _ _ [XPVNode ns]+ | nullNodeSet ns = XPVString ""+ | otherwise = XPVString (xpLocalPartOf . subtreeNT . headNodeSet $ ns)+xlocalName _ _ _ = XPVError "Call to function local-name with wrong arguments"++-- -----------------------------------------------------------------------------+-- |+-- string namespace-uri(node-set?):+-- returns the namespace URI of the expanded-name of the node in the argument node-set+-- that is first in document order.+-- If the argument node-set is empty, the first node has no expanded-name,+-- or the namespace URI of the expanded-name+-- is null, an empty string is returned. If the argument is omitted,+-- it defaults to a node-set with the context node as its only member++xnamespaceUri :: XFct+xnamespaceUri (_, _, cn) _ [] = XPVString (xpNamespaceOf . subtreeNT $ cn)+xnamespaceUri _ _ [XPVNode ns]+ | nullNodeSet ns = XPVString ""+ | otherwise = XPVString (xpNamespaceOf . subtreeNT . headNodeSet $ ns)+xnamespaceUri _ _ _ = XPVError "Call to function namespace-uri with wrong arguments"+++-- -----------------------------------------------------------------------------+-- |+-- string name(node-set?): +-- returns a string containing a QName representing the expanded-name of the node+-- in the argument node-set +-- that is first in document order. If the argument node-set is empty or the first+-- node has no expanded-name, +-- an empty string is returned. If the argument it omitted, it defaults to a node-set+-- with the context node as its only member.+-- Tim Walkenhorst: ++-- Bugfix: name(\/) is "" not "\/"!++xname :: XFct+xname (_, _, cn) _ [] = XPVString (xpNameOf . subtreeNT $ cn)+xname _ _ [XPVNode ns]+ | nullNodeSet ns = XPVString ""+ | otherwise = XPVString (xpNameOf . subtreeNT . headNodeSet $ ns)+xname _ _ _ = XPVError "Call to function name with wrong arguments"++-- ------------------------------------------------------------+-- string functions++-- |+-- some helper functions+getFirstPos :: String -> String -> Int+getFirstPos s sub = if (getFirstPos' s sub) > length s+ then -1+ else getFirstPos' s sub++-- -----------------------------------------------------------------------------++getFirstPos' :: String -> String -> Int+getFirstPos' [] _ = 2+getFirstPos' (x:xs) sub = if strStartsWith (x:xs) sub+ then 0+ else 1 + getFirstPos' xs sub++-- -----------------------------------------------------------------------------++strStartsWith :: String -> String -> Bool+strStartsWith a b = take (length b) a == b++-- -----------------------------------------------------------------------------+-- |+-- Returns the string-value of a node,+-- the value of a namespace node is not supported++stringValue :: NavXmlTree -> XPathValue+stringValue = XPVString . xpTextOf . self++{-+ textFilter + = getXCmt `orElse`+-- getXNamespace `orElse`+ multi isXText+ +-- = (isXTag `guards` multi isXText) `orElse`+-- (isXPi `guards` multi isXText) `orElse`+-- (isXAttr `guards` multi isXText) `orElse` +-- (isXText `guards` multi isXText) `orElse`+-- getXCmt+-}+++-- -----------------------------------------------------------------------------+-- |+-- string string(object?): converts an object to a string++xstring :: XFct+xstring _ _ [XPVNode ns]+ | nullNodeSet ns = XPVString ""+ | otherwise = stringValue . headNodeSet $ ns+xstring (_, _, cn) _ [] = stringValue cn++xstring _ _ [XPVNumber (Float a)]+ | a == (fromInteger $ round a) = XPVString (show ((round a)::Integer))+ | otherwise = XPVString (show a)+xstring _ _ [XPVNumber s] = XPVString (show s)++xstring _ _ [XPVBool True] = XPVString "true"+xstring _ _ [XPVBool False] = XPVString "false"++xstring _ _ [XPVString s] = XPVString s+xstring _ _ [XPVError e] = XPVError e+xstring _ _ _ = XPVError "Call to xstring with a wrong argument"++-- -----------------------------------------------------------------------------+-- |+-- string concat(string, string, string*): returns the concatenation of its arguments++xconcat :: XFct+xconcat c env args = XPVString (foldr (\ (XPVString s) -> (s ++)) "" (toXValue xstring c env args))++-- -----------------------------------------------------------------------------+-- |+-- boolean starts-with(string, string): +-- returns true if the first argument string starts +-- with the second argument string, and otherwise returns false++xstartsWith :: XFct+xstartsWith c env args = XPVBool $+ (\ ((XPVString a):[XPVString b]) -> strStartsWith a b) $+ toXValue xstring c env args++-- -----------------------------------------------------------------------------+-- |+-- boolean contains(string, string):+-- returns true if the first argument string contains the second argument string,+-- and otherwise returns false++xcontains :: XFct+xcontains c env args = XPVBool $+ (\ ((XPVString s):[XPVString sub]) -> getFirstPos s sub /= -1) $+ toXValue xstring c env args+++-- -----------------------------------------------------------------------------+-- |+-- string substring-before(string, string):+-- returns the substring of the first argument string that precedes the first occurrence of+-- the second argument string +-- in the first argument string, or the empty string if the first argument string does not+-- contain the second argument string++xsubstringBefore :: XFct+xsubstringBefore c env args = xsubstringBefore' c env (toXValue xstring c env args)++xsubstringBefore' :: XFct+xsubstringBefore' _ _ ((XPVString _):[XPVString []]) = XPVString ""+xsubstringBefore' _ _ ((XPVString s):[XPVString sub]) = XPVString (take (getFirstPos s sub) s)+xsubstringBefore' _ _ _ = XPVError "Call to xsubstringBefore' with a wrong argument"++-- -----------------------------------------------------------------------------+-- |+-- string substring-after(string, string):+-- returns the substring of the first argument string that follows the first occurrence of+-- the second argument string +-- in the first argument string, or the empty string if the first argument string does not+-- contain the second argument string++xsubstringAfter :: XFct+xsubstringAfter c env args = xsubstringAfter' c env (toXValue xstring c env args)++xsubstringAfter' :: XFct+xsubstringAfter' _ _ ((XPVString s):[XPVString []]) = XPVString s+xsubstringAfter' _ _ ((XPVString s):[XPVString sub]) = if getFirstPos s sub == -1+ then (XPVString "")+ else XPVString (drop ((getFirstPos s sub)+length sub) s)+xsubstringAfter' _ _ _ = XPVError "Call to xsubstringAfter' with a wrong argument"+++-- -----------------------------------------------------------------------------+-- |+-- string substring(string, number, number?):+-- returns the substring of the first argument starting at the position specified+-- in the second argument +-- with length specified in the third argument. If the third argument is not specified,+-- it returns the substring +-- starting at the position specified in the second argument and continuing to the end of the string.++xsubstring :: XFct+xsubstring c env (x:xs) = xsubstring' c env ((toXValue xstring c env [x])++(toXValue xnumber c env xs))+xsubstring _ _ _ = XPVError "Call to xsubstring with a wrong argument"++xsubstring' :: XFct+xsubstring' c env ((XPVString s):start:[])+ = case xround c env [start] of+ XPVNumber NaN -> XPVString ""+ XPVNumber PosInf -> XPVString ""+ XPVNumber (Float f) -> XPVString (drop ((round f)-1) s)+ XPVNumber _ -> XPVString s+ _ -> XPVError "Call to xsubstring' with a wrong argument"++xsubstring' c env ((XPVString s):start:[end])+ = case xPathAdd Plus (xround c env [start]) (xround c env [end]) of+ XPVNumber (Float f) -> xsubstring' c env ( (XPVString (take ((round f) -1) s)):[start])+ XPVNumber PosInf -> xsubstring' c env ( (XPVString s):[start])+ XPVNumber _ -> XPVString ""+ _ -> XPVError "Call to xsubstring' with a wrong argument"+xsubstring' _ _ _ = XPVError "Call to xsubstring' with a wrong argument"+++-- -----------------------------------------------------------------------------+-- |+-- number string-length(string?):+-- returns the number of characters in the string. If the argument is omitted,+-- it defaults to the context node +-- converted to a string, in other words the string-value of the context node.++xstringLength :: XFct+xstringLength c@(_, _, cn) env [] = XPVNumber (Float (fromIntegral $ length s))+ where+ XPVString s = xstring c env [XPVNode $ singletonNodeSet cn]++xstringLength c env args = XPVNumber $+ (\[XPVString s] -> int2XPNumber $ length s) $+ toXValue xstring c env args+++-- -----------------------------------------------------------------------------+-- |+-- string normalize-space(string?):+-- returns the argument string with whitespace normalized by stripping leading+-- and trailing whitespace and replacing sequences +-- of whitespace characters by a single space. If the argument is omitted,+-- it defaults to the context node converted to a string, +-- in other words the string-value of the context node.+-- The string is parsed by a function parseStr from XPathParser module. <-- No longer! Tim Walkenhorst++xnormalizeSpace :: XFct+xnormalizeSpace c@(_, _, cn) env [] = (\ (XPVString s) -> XPVString $ normStr s) $+ xstring c env [XPVNode $ singletonNodeSet cn]+xnormalizeSpace c env args = (\ [XPVString s] -> XPVString $ normStr s) $+ toXValue xstring c env args++-- Tim Walkenhorst normStr replaces the use of parseStr...+normStr :: String -> String+normStr = unwords . words++-- -----------------------------------------------------------------------------+-- |+-- string translate(string, string, string):+-- returns the first argument string with occurrences of characters in the second argument string replaced by the character at +-- the corresponding position in the third argument string++xtranslate :: XFct+xtranslate c env args = xtranslate' c env (toXValue xstring c env args)++xtranslate' :: XFct+xtranslate' _ _ ((XPVString a):(XPVString b):[XPVString c])+ = XPVString (replace a b c)+xtranslate' _ _ _ = XPVError "Call to xtranslate' with a wrong argument"++replace :: String -> String -> String -> String+replace str [] _ = str++-- remove all characters, if there is no corresponding character in the third argument+replace str (x:xs) [] = replace [ s | s <- str, x /= s] xs []++replace str (x:xs) (y:ys) = replace (rep x y str) xs ys+ where -- replace all characters in the first argument+ rep :: Char -> Char -> String -> String+ rep a b = foldr (\c -> if c == a then (b:) else (c:)) ""++-- ------------------------------------------------------------+-- boolean functions++-- |+-- boolean boolean(object): converts its argument to a boolean value++xboolean :: XFct+xboolean _ _ [XPVNumber a] = XPVBool (a/= NaN && a/= Neg0 && a/= Pos0)+xboolean _ _ [XPVString s] = XPVBool (length s /= 0)+xboolean _ _ [XPVBool b] = XPVBool b+xboolean _ _ [XPVNode ns] = XPVBool (not . nullNodeSet $ ns)+xboolean _ _ [XPVError e] = XPVError e+xboolean _ _ _ = XPVError "Call to xboolean with a wrong argument"+++-- -----------------------------------------------------------------------------+-- |+-- boolean not(boolean): returns true if its argument is false, and false otherwise+xnot :: XFct+xnot c env args = XPVBool ( (\ (XPVBool b) -> not b) (xboolean c env args) )++-- -----------------------------------------------------------------------------+-- |+-- boolean true(): returns true+xtrue :: XFct+xtrue _ _ _ = XPVBool True++-- -----------------------------------------------------------------------------+-- |+-- boolean false(): returns false+xfalse :: XFct+xfalse _ _ _ = XPVBool False++-- -----------------------------------------------------------------------------+-- |+-- boolean lang(string):+-- returns true or false depending on whether the language of the context node as specified by xml:lang attributes +-- is the same as or is a sublanguage of the language specified by the argument string++-- -----------------------------------------------------------------------------+--+-- function needs namespaces which are not supported by the toolbox (???)++xlang :: XFct+xlang _ _ _ = XPVError "namespaces are not supported"++-- xlang c env args+-- = (\ (_, _, cn) [XPVString s] -> ...) c (toXValue xstring c env args)++-- ------------------------------------------------------------+-- number functions++-- |+-- number number(object?): converts its argument to a number+xnumber :: XFct+xnumber c@(_, _, cn) env [] = (\ (XPVString s) -> parseNumber s) (xstring c env [XPVNode $ singletonNodeSet cn])+xnumber c env [n@(XPVNode _)] = (\ (XPVString s) -> parseNumber s) (xstring c env [n])++xnumber _ _ [XPVBool b]+ | b = XPVNumber (Float 1)+ | otherwise = XPVNumber Pos0++xnumber _ _ [XPVString s] = parseNumber s+xnumber _ _ [XPVNumber a] = XPVNumber a+xnumber _ _ [XPVError e] = XPVError e+xnumber _ _ _ = XPVError "Call to xnumber with a wrong argument"++-- -----------------------------------------------------------------------------+-- |+-- number sum(node-set): +-- returns the sum, for each node in the argument node-set, of the result of +-- converting the string-values of the node to a number++xsum :: XFct+xsum c env [XPVNode ns]+ | nullNodeSet ns = XPVNumber NaN+ | otherwise = foldr1 (\ a b -> (xPathAdd Plus a b)) (getValues ns)+ where+ getValues :: NodeSet -> [XPathValue]+ getValues = foldr (\ n -> ([xnumber c env $ [stringValue n] ] ++) ) [] . fromNodeSet++xsum _ _ _ = XPVError "The value of the function sum is not a nodeset"++-- -----------------------------------------------------------------------------+-- |+-- number floor(number): returns the largest (closest to positive infinity) number that is not greater +-- than the argument and that is an integer++xfloor :: XFct+xfloor c env args = xfloor' (toXValue xnumber c env args)+ where+ xfloor' [XPVNumber (Float f)]+ | f > 0 && f < 1 = XPVNumber Pos0+ | otherwise = XPVNumber (Float (fromInteger $ floor f))+ xfloor' [XPVNumber a] = XPVNumber a+ xfloor' _ = XPVError "Call to xfloor' without a number"++-- -----------------------------------------------------------------------------+-- |+-- number ceiling(number): returns the smallest (closest to negative infinity) number that is not less +-- than the argument and that is an integer++xceiling :: XFct+xceiling c env args = xceiling' (toXValue xnumber c env args)+ where+ xceiling' [XPVNumber (Float f)]+ | f < 0 && f > -1 = XPVNumber Pos0+ | otherwise = XPVNumber (Float (fromInteger $ ceiling f))+ xceiling' [XPVNumber a] = XPVNumber a+ xceiling' _ = XPVError "Call to xceiling' without a number"++-- -----------------------------------------------------------------------------+-- |+-- number round(number):+-- returns the number that is closest to the argument and that is an integer. +-- If there are two such numbers, then the one that is closest to positive infinity is returned.++xround :: XFct+xround c env args = xround' c env (toXValue xnumber c env args)++xround' :: XFct+xround' _ _ [XPVNumber (Float f)]+ | f < 0 && f >= -0.5 = XPVNumber Neg0+ | f >= 0 && f < 0.5 = XPVNumber Pos0+ | otherwise = XPVNumber (Float (fromInteger $ xPathRound f))+ where+ xPathRound a = if a - (fromInteger $ floor a) < 0.5+ then floor a+ else floor (a+1)++xround' _ _ [XPVNumber a] = XPVNumber a+xround' _ _ _ = XPVError "Call to xround' without a number"++-- -----------------------------------------------------------------------------+-- |+-- node-set key(string, object):+-- does for keys what the id function does for IDs+-- The first argument specifies the name of the key.+-- When the second argument is of type node-set, then the result is the+-- union of the result of applying the key function to the string value+-- of each of the nodes in the argument node-set.+-- When the second argument is of any other type, the argument is+-- converted to a string +xkey :: XFct+xkey _ env ((XPVString s) : [XPVNode ns])+ = isInKey (getKeyTab env) s (strValues . fromNodeSet $ ns)+ where+ strValues = map ((\ (XPVString str) -> str) . stringValue)++xkey c env ((XPVString s) : arg) -- = isInKey (getKeyTab env) s ( (\(XPVString s) -> words s) (xstring c env arg))+ = isInKey (getKeyTab env) s [str]+ where+ XPVString str = xstring c env arg++xkey _ _ _ = XPVError "Call to xkey with a wrong argument"+++isInKey :: KeyTab -> String -> [String] -> XPathValue+isInKey kt kn kv = XPVNode . toNodeSet $ ts+ where+ (_, _, ts) = unzip3 $ concat $ map (isKeyVal (isKeyName kt kn)) kv++isKeyName :: KeyTab -> String -> KeyTab+isKeyName kt kn = filter (isOfKeyName kn) kt++isKeyVal :: KeyTab -> String -> KeyTab+isKeyVal kt kv = filter (isOfKeyValue kv) kt++isOfKeyName :: String -> (QName, String, NavXmlTree) -> Bool+isOfKeyName kn (qn, _, _) = localPart qn == kn+++isOfKeyValue :: String -> (QName, String, NavXmlTree) -> Bool+isOfKeyValue kv (_, v, _) = v == kv+++-- -----------------------------------------------------------------------------+-- |+-- string format-number(number, string, string?):+-- converts its first argument to a string using the format pattern string+-- specified by the second argument and the decimal-format named by the+-- third argument, or the default decimal-format, if there is no third argument++xformatNumber :: XFct+xformatNumber c env (x:xs) = xsubstring' c env (toXValue xstring c env [x] ++ toXValue xnumber c env xs)+xformatNumber _ _ _ = XPVError "Call to xformatNumber with a wrong argument"+++-- -----------------------------------------------------------------------------++-- Poor man's document(...) function. Opens exactly one document. +-- Does not support "fragment identifiers". "Base-URI" is always current directory.+-- Should still be good enough for home use.++xdocument :: XFct+xdocument c e val = XPVNode . toNodeSet . (\ (XPVString s) -> xdocument' s) . xstring c e $ val++xdocument' :: String -> [NavXmlTree]+xdocument' uri = map ntree $+ unsafePerformIO $+ runX ( readDocument [(a_validate, v_0)] uri+ >>>+ addAttr "rootId" ("doc " ++ uri)+ )++-- -----------------------------------------------------------------------------++-- generate-id, should be fully compliant with XSLT specification.++xgenerateId :: XFct+xgenerateId _ _ [XPVNode ns]+ | not (nullNodeSet ns) = xgenerateId' . headNodeSet $ ns++xgenerateId (_, _, node) _ [] = xgenerateId' node+xgenerateId _ _ _ = error "illegal arguments in xgenerateId"++xgenerateId' :: NavXmlTree -> XPathValue+xgenerateId' = XPVString . ("id_"++) . str2XmlId . show . nodeID . Just++str2XmlId :: String -> String+str2XmlId = concatMap convert+ where+ convert c = if isAscii c && (isUpper c || isLower c || isDigit c)+ then [c]+ else "_" ++ (show $ ord c) ++ "_"++-- ------------------------------------------------------------++xpNamePart :: LA XmlTree String -> XmlTree -> String+xpNamePart getNp+ = concat+ .+ runLA ( ifA isRoot+ (constA "")+ getNp+ )++xpLocalPartOf :: XmlTree -> String+xpLocalPartOf = xpNamePart getLocalPart++xpNamespaceOf :: XmlTree -> String+xpNamespaceOf = xpNamePart getNamespaceUri++xpNameOf :: XmlTree -> String+xpNameOf = xpNamePart getName++getValue :: String -> XmlTree -> String+getValue n = concat . runLA (getAttrValue n)++xpTextOf :: XmlTree -> String+xpTextOf = concat . runLA (xshow ((getCmt >>> mkText) <+> deep isText))++-- ------------------------------------------------------------
+ src/Text/XML/HXT/XPath/XPathKeywords.hs view
@@ -0,0 +1,57 @@+-- |+-- $Id: XPathKeywords.hs,v 1.1 2004/09/02 19:12:05 hxml Exp $+--+-- the XPath keywords+--+++module Text.XML.HXT.XPath.XPathKeywords+where++-- ------------------------------------------------------------+--+-- string constants for representing XPath keywords and axis++a_ancestor, -- axisNames+ a_ancestor_or_self,+ a_attribute,+ a_child,+ a_descendant,+ a_descendant_or_self,+ a_following,+ a_following_sibling,+ a_namespace,+ a_parent,+ a_preceding,+ a_preceding_sibling,+ a_self :: String+++n_comment, -- nodeTypes+ n_text,+ n_processing_instruction,+ n_node :: String++-- ------------------------------------------------------------++a_ancestor = "ancestor" +a_ancestor_or_self = "ancestor-or-self" +a_attribute = "attribute" +a_child = "child" +a_descendant = "descendant" +a_descendant_or_self = "descendant-or-self" +a_following = "following" +a_following_sibling = "following-sibling" +a_namespace = "namespace" +a_parent = "parent" +a_preceding = "preceding" +a_preceding_sibling = "preceding-sibling" +a_self = "self" +++n_comment = "comment"+n_text = "text"+n_processing_instruction = "processing-instruction"+n_node = "node"++-- ------------------------------------------------------------
+ src/Text/XML/HXT/XPath/XPathParser.hs view
@@ -0,0 +1,652 @@+-- ------------------------------------------------------------++{- |+ Module : Text.XML.HXT.XPath.XPathParser+ Copyright : Copyright (C) 2006-2008 Uwe Schmidt+ License : MIT++ Maintainer : Uwe Schmidt (uwe@fh-wedel.de)+ Stability : experimental+ Portability: portable++ the XPath Parser++-}++-- ------------------------------------------------------------++module Text.XML.HXT.XPath.XPathParser+ ( parseNumber+ , parseXPath+ )+where++import Data.Maybe++import Text.ParserCombinators.Parsec++import Text.XML.HXT.DOM.TypeDefs++import Text.XML.HXT.XPath.XPathKeywords+import Text.XML.HXT.XPath.XPathDataTypes++import Text.XML.HXT.Parser.XmlTokenParser+ ( separator+ , systemLiteral+ , skipS0+ , ncName+ , qName+ )++lookupNs :: NsEnv -> XName -> XName+lookupNs uris prefix+ -- downwards compatibility: if namespace env is not supported+ -- no error is raised, but the uri remains empty+ -- not conformant to XPath spec:+ -- If namespaces are used, a complete env must be supported,+ -- but we don't care about this+ = fromMaybe nullXName $ lookup prefix uris++enhanceAttrQName :: NsEnv -> QName -> QName+enhanceAttrQName uris qn+ | isNullXName (namePrefix' qn) = qn+ | otherwise = enhanceQName uris qn++enhanceQName :: NsEnv -> QName -> QName+enhanceQName uris qn = setNamespaceUri' ( lookupNs uris (namePrefix' qn) ) qn++enhanceQN :: AxisSpec -> NsEnv -> QName -> QName+enhanceQN Attribute = enhanceAttrQName+enhanceQN _ = enhanceQName++type XParser a = GenParser Char NsEnv a++-- ------------------------------------------------------------+-- parse functions which are used in the XPathFct module++-- |+-- parsing a number, parseNumber is used in "XPathFct"+-- by the number function+--+-- - returns : the parsed number as 'XPNumber' float+-- or 'XPVNumber' 'NaN' in case of error+parseNumber :: String -> XPathValue+parseNumber s+ = case (runParser parseNumber' [] {- Map.empty -} "" s) of+ Left _ -> XPVNumber NaN+ Right x -> if (read x :: Float) == 0+ then (XPVNumber Pos0)+ else XPVNumber (Float (read x))++parseNumber' :: XParser String+parseNumber'+ = do+ skipS0+ m <- option "" (string "-")+ n <- number+ skipS0+ eof+ return (m ++ n)++-- ------------------------------------------------------------+++-- |+-- the main entry point:+-- parsing a XPath expression++parseXPath :: XParser Expr+parseXPath+ = do+ skipS0+ xPathExpr <- expr+ skipS0+ eof+ return xPathExpr+++-- some useful token and symbol parser+lpar, rpar, lbra, rbra, slash, dslash :: XParser ()++lpar = tokenParser (symbol "(")+rpar = tokenParser (symbol ")")+lbra = tokenParser (symbol "[")+rbra = tokenParser (symbol "]")+slash = tokenParser (symbol "/")+dslash = tokenParser (symbol "//")+++tokenParser :: XParser String -> XParser ()+tokenParser p+ = try ( do+ skipS0+ _ <- p+ skipS0+ )+++symbolParser :: (String, a) -> XParser a+symbolParser (s,a)+ = do+ tokenParser (symbol s)+ return a+++symbol :: String -> XParser String+symbol s = try (string s)++++-- operation parser+orOp, andOp, eqOp, relOp, addOp, multiOp, unionOp :: XParser Op++orOp = symbolParser ("or", Or)+andOp = symbolParser ("and", And)++eqOp+ = symbolParser ("=", Eq)+ <|> + symbolParser ("!=", NEq)++relOp+ = choice [ symbolParser ("<=", LessEq)+ , symbolParser (">=", GreaterEq)+ , symbolParser ("<", Less)+ , symbolParser (">", Greater)+ ]++addOp+ = symbolParser ("+", Plus)+ <|> + symbolParser ("-", Minus)+++multiOp+ = choice [ symbolParser ("*", Mult)+ , symbolParser ("mod", Mod)+ , symbolParser ("div", Div)+ ]+++unionOp = symbolParser ("|", Union)++-- ------------------------------------------------------------++mkExprNode :: Expr -> [(Op, Expr)] -> Expr+mkExprNode e1 [] = e1+mkExprNode e1 l@((op, _): _) = + if null rest+ then GenExpr op (e1:(map snd l))+ else GenExpr op $ (e1:(map snd $ init same)) ++ [mkExprNode (snd $ last same) rest]+ where + (same, rest) = span ((==op) . fst) l+ +-- Tim Walkenhorst, original expr. below:+-- It seems mkExprNode is called only with operators of the same precedence, that should make it fixable+-- FIXED, see above!+--mkExprNode e1 l@((op, _): _) = GenExpr op (e1:(map snd l)) -- Less than ideal: 1+1-1 = 3 ???+++--GenExpr op (e1:(map snd l))+++exprRest :: XParser Op -> XParser Expr -> XParser (Op, Expr)+exprRest parserOp parserExpr+ = do+ op <- parserOp+ e2 <- parserExpr+ return (op, e2)+++-- ------------------------------------------------------------++-- abbreviation of "//"+descOrSelfStep :: XStep +descOrSelfStep = (Step DescendantOrSelf (TypeTest XPNode) [])++-- ------------------------------------------------------------+-- Location Paths (2)+++-- [1] LocationPath +locPath :: XParser LocationPath+locPath+ = absLocPath+ <|> + relLocPath'+++-- [2] AbsoluteLocationPath+absLocPath :: XParser LocationPath+absLocPath+ = do -- [10]+ dslash+ s <- relLocPath+ return (LocPath Abs ([descOrSelfStep] ++ s))+ <|> + do+ slash+ s <- option [] relLocPath+ return (LocPath Abs s)+ <?> "absLocPath"+++-- [3] RelativeLocationPath+relLocPath' :: XParser LocationPath+relLocPath'+ = do+ rel <- relLocPath+ return (LocPath Rel rel)++relLocPath :: XParser [XStep]+relLocPath+ = do+ s1 <- step+ s2 <- many (step')+ return ([s1] ++ (concat s2))+ <?> "relLocPath"+++-- Location Steps (2.1)+--+-- [4] Step+step' :: XParser [XStep]+step'+ = do -- [11]+ dslash+ s <- step+ return [descOrSelfStep,s]+ <|>+ do+ slash+ s <- step+ return [s]+ <?> "step'"++step :: XParser XStep+step+ = abbrStep+ <|>+ do+ as <- axisSpecifier'+ nt <- nodeTest as+ pr <- many predicate+ return (Step as nt pr)+ <?> "step"+++-- [5] AxisSpecifier+axisSpecifier' :: XParser AxisSpec+axisSpecifier'+ = do -- [13]+ tokenParser (symbol "@")+ return Attribute+ <|>+ do+ as <- option Child ( try ( do -- child-axis is default-axis+ a <- axisSpecifier+ tokenParser (symbol "::")+ return a+ )+ )+ return as+ <?> "axisSpecifier'"+++-- Axes (2.2)+--+-- [6] AxisName+axisSpecifier :: XParser AxisSpec+axisSpecifier+ = choice [ symbolParser (a_ancestor_or_self, AncestorOrSelf)+ , symbolParser (a_ancestor, Ancestor)+ , symbolParser (a_attribute, Attribute)+ , symbolParser (a_child, Child)+ , symbolParser (a_descendant_or_self, DescendantOrSelf)+ , symbolParser (a_descendant, Descendant)+ , symbolParser (a_following_sibling, FollowingSibling)+ , symbolParser (a_following, Following)+ , symbolParser (a_namespace, Namespace)+ , symbolParser (a_parent, Parent)+ , symbolParser (a_preceding_sibling, PrecedingSibling)+ , symbolParser (a_preceding, Preceding)+ , symbolParser (a_self, Self)+ ]+ <?> "axisSpecifier"+++-- Node Tests (2.3)+--+-- [7] NodeTest+nodeTest :: AxisSpec -> XParser NodeTest+nodeTest as+ = do+ nt <- try nodeType'+ return (TypeTest nt)+ <|>+ do+ processInst <- pI+ return (PI processInst)+ <|>+ do+ nt <- nameTest as+ return (NameTest nt)+ <?> "nodeTest"++pI :: XParser String+pI+ = do+ tokenParser (symbol n_processing_instruction)+ li <- between lpar rpar literal+ return li+ <?> "Processing-Instruction"+++-- Predicates (2.4)+--+-- [8] Predicate+-- [9] PredicateExpr+predicate :: XParser Expr+predicate + = do+ ex <- between lbra rbra expr+ return ex+++-- Abbreviated Syntax (2.5)+--+-- [10] AbbreviatedAbsoluteLocationPath: q.v. [2]+-- [11] AbbreviatedRelativeLocationPath: q.v. [4]++-- [12] AbbreviatedStep+abbrStep :: XParser XStep+abbrStep + = do+ tokenParser (symbol "..")+ return (Step Parent (TypeTest XPNode) [])+ <|>+ do+ tokenParser (symbol ".")+ return (Step Self (TypeTest XPNode) [])+ <?> "abbrStep"++-- [13] AbbreviatedAxisSpecifier: q.v. [5]+++-- ------------------------------------------------------------+-- Expressions (3)+++-- Basics (3.1)+--+-- [14] Expr+expr :: XParser Expr+expr = orExpr+++-- [15] PrimaryExpr+primaryExpr :: XParser Expr+primaryExpr+ = do+ vr <- variableReference+ return (VarExpr vr)+ <|>+ do+ ex <- between lpar rpar expr+ return ex+ <|>+ do+ li <- literal+ return (LiteralExpr li)+ <|> + do+ num <- number+ return (NumberExpr (Float $ read num))+ <|>+ do+ fc <- functionCall+ return (fc)+ <?> "primaryExpr"+++-- Function Calls (3.2)+--+-- [16] FunctionCall+-- [17] Argument+functionCall :: XParser Expr+functionCall+ = do+ fn <- functionName+ arg <- between lpar rpar ( sepBy expr (separator ',') )+ return (FctExpr fn arg)+ <?> "functionCall"+++-- Node-sets (3.3)+--+-- [18] UnionExpr+unionExpr :: XParser Expr+unionExpr+ = do+ e1 <- pathExpr+ eRest <- many (exprRest unionOp pathExpr)+ return (mkExprNode e1 eRest)+++-- [19] PathExpr+pathExpr :: XParser Expr+pathExpr+ = do+ fe <- try filterExpr+ path <- do+ dslash+ LocPath t1 t2 <- relLocPath'+ return (PathExpr (Just fe) (Just (LocPath t1 ([descOrSelfStep] ++ t2))))+ <|>+ do+ slash+ relPath <- relLocPath'+ return (PathExpr (Just fe) (Just relPath))+ <|>+ return fe+ return path+ <|>+ do+ lp <- locPath+ return (PathExpr Nothing (Just lp))+ <?> "pathExpr"+++-- [20] FilterExpr+filterExpr :: XParser Expr+filterExpr+ = do+ prim <- primaryExpr+ predicates <- many predicate+ if length predicates > 0+ then return (FilterExpr (prim : predicates))+ else return prim+ <?> "filterExpr"+++-- Booleans (3.4)+--+-- [21] OrExpr+orExpr :: XParser Expr+orExpr+ = do+ e1 <- andExpr+ eRest <- many (exprRest orOp andExpr)+ return (mkExprNode e1 eRest)+ <?> "orExpr"+++-- [22] AndExpr+andExpr :: XParser Expr+andExpr+ = do+ e1 <- equalityExpr+ eRest <- many (exprRest andOp equalityExpr)+ return (mkExprNode e1 eRest)+ <?> "andExpr"+++-- [23] EqualityExpr+equalityExpr :: XParser Expr+equalityExpr+ = do+ e1 <- relationalExpr+ eRest <- many (exprRest eqOp relationalExpr)+ return (mkExprNode e1 eRest)+ <?> "equalityExpr"+++-- [24] RelationalExpr+relationalExpr :: XParser Expr+relationalExpr+ = do+ e1 <- additiveExpr+ eRest <- many (exprRest relOp additiveExpr)+ return (mkExprNode e1 eRest)+ <?> "relationalExpr"+++-- Numbers (3.5)+--+-- [25] AdditiveExpr+additiveExpr :: XParser Expr+additiveExpr+ = do+ e1 <- multiplicativeExpr+ eRest <- many (exprRest addOp multiplicativeExpr)+ return (mkExprNode e1 eRest)+ <?> "additiveExpr"+++-- [26] MultiplicativeExpr+multiplicativeExpr :: XParser Expr+multiplicativeExpr+ = do+ e1 <- unaryExpr+ eRest <- many (exprRest multiOp unaryExpr)+ return (mkExprNode e1 eRest)+ <?> "multiplicativeExpr"+++-- [27] UnaryExpr+unaryExpr :: XParser Expr+unaryExpr+ = do+ tokenParser (symbol "-")+ u <- unaryExpr+ return (GenExpr Unary [u])+ <|>+ do+ u <- unionExpr+ return u+ <?> "unaryExpr"+++-- Lexical Structure (3.7)+--+-- [29] Literal+-- systemLiteral from XmlParser is used+literal :: XParser String+literal = systemLiteral+++-- [30] Number+number :: XParser String+number+ = do+ tokenParser (symbol ".")+ d <- many1 digit+ return ("0." ++ d)+ <|>+ do+ d <- many1 digit+ d1 <- option "" ( do+ tokenParser (symbol ".")+ d2 <- option "0" (many1 digit)+ return ("." ++ d2)+ )+ return (d ++ d1)+ <?> "number"+++-- [35] FunctionName+-- no nodetype name is allowed as a function name+-- Tim Walkenhorst:+-- Change in String encoding for function name+--+-- previoulsy: new:+-- +-- name name+-- pref:name {http://uri-for-pref}name++functionName :: XParser String+functionName+ = try ( do + (p, n) <- qName+ uris <- getState+ u <- return $ if null p+ then ""+ else '{' : show (lookupNs uris (newXName p)) ++ "}"+ let fn = (u ++ n) in+ if fn `elem` ["processing-instruction", "comment", "text", "node"]+ then fail ("function name: " ++ fn ++ "not allowed")+ else return fn+ )+ <?> "functionName"+++-- [36] VariableReference+variableReference :: XParser (String, String)+variableReference+ = do+ tokenParser (symbol "$")+ (p,n) <- qName+ uris <- getState+ return (show (lookupNs uris (newXName p)), n)+ <?> "variableReference"+++-- [37] NameTest+nameTest :: AxisSpec -> XParser QName+nameTest as+ = do tokenParser (symbol "*")+ uris <- getState+ return (enhanceQN as uris $ mkPrefixLocalPart "" "*")+ <|>+ try ( do pre <- ncName+ _ <- symbol ":*"+ uris <- getState+ return (enhanceQN as uris $ mkPrefixLocalPart pre "*")+ )+ <|>+ do (pre,local) <- qName+ uris <- getState+ return (enhanceQN as uris $ mkPrefixLocalPart pre local)+ <?> "nameTest"++ +-- [38] NodeType+nodeType' :: XParser XPathNode+nodeType' + = do+ nt <- nodeType+ lpar+ rpar+ return nt+ <?> "nodeType'"+ +nodeType :: XParser XPathNode+nodeType + = choice [ symbolParser (n_comment, XPCommentNode)+ , symbolParser (n_text, XPTextNode)+ , symbolParser (n_processing_instruction, XPPINode)+ , symbolParser (n_node, XPNode)+ ]+ <?> "nodeType"++-- ------------------------------------------------------------
+ src/Text/XML/HXT/XPath/XPathToNodeSet.hs view
@@ -0,0 +1,67 @@+-- |+-- 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++-- -----------------------------------------------------------------------------
+ src/Text/XML/HXT/XPath/XPathToString.hs view
@@ -0,0 +1,135 @@+-- ------------------------------------------------------------++{- |+ Module : Text.XML.HXT.XPath.XPathToString+ Copyright : Copyright (C) 2008 - infinity: Uwe Schmidt+ License : MIT++ Maintainer : Uwe Schmidt (uwe@fh-wedel.de)+ Stability : experimental+ Portability: portable++ Format an expression or value in tree- or string-representation++-}++-- ------------------------------------------------------------++module Text.XML.HXT.XPath.XPathToString+ ( expr2XPathTree+ , xPValue2String+ , xPValue2XmlTrees+ , nt2XPathTree+ , pred2XPathTree+ , toXPathTree+ , formatXPathTree+ )+where++-- import Text.XML.HXT.DOM.XmlTree++import Text.XML.HXT.DOM.Interface+import Text.XML.HXT.DOM.XmlNode ( mkText+ , mkError+ )+import Text.XML.HXT.DOM.FormatXmlTree ( formatXmlTree )+import Text.XML.HXT.XPath.XPathDataTypes++import Data.Char ( toLower )++-- ------------------------------------------------------------++type XPathTree = NTree String++-- -----------------------------------------------------------------------------+-- |+-- Convert an navigable tree in a xmltree+--+toXPathTree :: [NavTree a] -> [NTree a]+toXPathTree = map subtreeNT++-- -----------------------------------------------------------------------------++formatXPathTree :: Expr -> String+formatXPathTree = formatTree id . expr2XPathTree++-- -----------------------------------------------------------------------------+-- |+-- Format a XPath-value in string representation.+-- Text output is done by 'formatXmlTree' for node-sets (trees),+-- all other values are represented as strings.+--++xPValue2String :: XPathValue -> String+xPValue2String (XPVNode ns) = foldr (\ t -> ((formatXmlTree t ++ "\n") ++)) "" (toXPathTree . fromNodeSet $ ns)+xPValue2String (XPVBool b) = map toLower (show b)+xPValue2String (XPVNumber (Float f)) = show f+xPValue2String (XPVNumber s) = show s+xPValue2String (XPVString s) = s+xPValue2String (XPVError s) = "Error: " ++ s++-- -----------------------------------------------------------------------------+-- |+-- Convert a a XPath-value into XmlTrees.+--++xPValue2XmlTrees :: XPathValue -> XmlTrees+xPValue2XmlTrees (XPVNode ns) = toXPathTree . fromNodeSet $ ns+xPValue2XmlTrees (XPVBool b) = xtext (show b)+xPValue2XmlTrees (XPVNumber (Float f)) = xtext (show f)+xPValue2XmlTrees (XPVNumber s) = xtext (show s)+xPValue2XmlTrees (XPVString s) = xtext s+xPValue2XmlTrees (XPVError s) = xerr s++xtext, xerr :: String -> XmlTrees+xtext = (:[]) . mkText++xerr = (:[]) . mkError c_err+++-- -----------------------------------------------------------------------------+-- |+-- Format a parsed XPath-expression in tree representation.+-- Text output is done by 'formatXmlTree'+--+expr2XPathTree :: Expr -> XPathTree+expr2XPathTree (GenExpr op ex) = NTree (show op) (map expr2XPathTree ex)+expr2XPathTree (NumberExpr f) = NTree (show f) []+expr2XPathTree (LiteralExpr s) = NTree s []+expr2XPathTree (VarExpr name) = NTree ("Var: " ++ show name) []+expr2XPathTree (FctExpr n arg) = NTree ("Fct: " ++ n) (map expr2XPathTree arg)++expr2XPathTree (FilterExpr []) = NTree "" []+expr2XPathTree (FilterExpr (primary:predicate))+ = NTree "FilterExpr" [expr2XPathTree primary, pred2XPathTree predicate]++expr2XPathTree (PathExpr Nothing (Just lp))+ = locpath2XPathTree lp+expr2XPathTree (PathExpr (Just fe) (Just lp))+ = NTree "PathExpr" [expr2XPathTree fe, locpath2XPathTree lp]+expr2XPathTree (PathExpr _ _) = NTree "" []++locpath2XPathTree :: LocationPath -> XPathTree+locpath2XPathTree (LocPath rel steps) = NTree (show rel ++ "LocationPath") (map step2XPathTree steps)+++step2XPathTree :: XStep -> XPathTree+step2XPathTree (Step axis nt []) = NTree (show axis) [nt2XPathTree nt]+step2XPathTree (Step axis nt expr) = NTree (show axis) [nt2XPathTree nt, pred2XPathTree expr]++nt2XPathTree :: NodeTest -> XPathTree+nt2XPathTree (TypeTest s) = NTree ("TypeTest: "++ typeTest2String s) []+nt2XPathTree (PI s) = NTree ("TypeTest: processing-instruction("++ show s ++ ")") []+nt2XPathTree (NameTest s) = NTree ("NameTest: "++ show s) []+++pred2XPathTree :: [Expr] -> XPathTree+pred2XPathTree exprL = NTree "Predicates" (map expr2XPathTree exprL)++typeTest2String :: XPathNode -> String+typeTest2String XPNode = "node()"+typeTest2String XPCommentNode = "comment()"+typeTest2String XPPINode = "processing-instruction()"+typeTest2String XPTextNode = "text()"++-- ------------------------------------------------------------