# Features covered: domDoc and docObj command
#
# This file contains a collection of tests for the two interfaces to
# DOM docs, the token interface (the domDoc command) and the tcl
# command interface ([$docObj method ...]).
#
#    domDoc-1.*:  asXML, asHTML
#    domDoc-2.*:  publicId, systemId
#    domDoc-3.*:  toXSLTcmd
#    domDoc-4.*:  asText
#    domDoc-5.*:  normalize
#    domDoc-6.*:  nodetype
#    domDoc-7.*:  insertBefore
#    domDoc-8.*:  insertBeforeFromScript
#    domDoc-9.*:  replaceChild
#    domDoc-10.*: getElementById
#    domDoc-11.*: firstChild
#    domDoc-12.*: lastChild
#    domDoc-13.*: appendChild
#    domDoc-14.*: removeChild
#    domDoc-15.*: hasChildNodes
#    domDoc-16.*: childNodes
#    domDoc-17.*: ownerDocument
#    domDoc-18.*: appendFromList
#    domDoc-19.*: appendXML
#    domDoc-20.*: selectNodes
#    domDoc-21.*: baseURI
#    domDoc-22.*: appendFromScript
#    domDoc-23.*: getElementsByTagNameNS
#    domDoc-24.*: cdataSectionElements
#    domDoc-25.*: selectNodesNamespaces
#    domDoc-26.*: fragments list
#    domDoc-27.*: deleteXPathCache
#    domDoc-28.*: createElementNS
#    domDoc-29.*: asCanonicalXML
#    domDoc-30.*: command argument parsing
#
# Copyright (c) 2004 - 2007 Rolf Ade.

source [file join [file dir [info script]] loadtdom.tcl]

test domDoc-1.1 {asXML -escapeNonASCII} {
    set doc [dom parse [tdom::xmlReadFile \
            [file join [file dir [info script]] data/i18n_1.xml]]]
    set result [$doc asXML -escapeNonASCII]
    $doc delete
    set result
} {<test>&#1072;&#1073;&#1074;&#1075;&#1076;&#1077;&#1078;&#1079;&#1080;&#1081;</test>
}

test domDoc-1.2 {asXML -escapeNonASCII; comments and PI's are not altered} {
    set doc [dom parse [tdom::xmlReadFile \
            [file join [file dir [info script]] data/i18n_2.xml]]]
    set result [$doc asXML -indent none -escapeNonASCII]
    $doc delete
    set result
} "<root withUmlauts=\"&#228;&#246;&#252;&#223;\"><!-- A comment with german umlauts: \u00E4\u00F6\u00FC\u00DF --><?\u00E4\u00F6\u00FC\u00DF A processing node with german umlauts?>
german umlauts: &#228;&#246;&#252;&#223;
</root>"

test domDoc-1.3 {asHTML -escapeNonASCII -htmlEntities} {
    set doc [dom parse {<html><body>&#228;&#xfc;&#8222;&#8223;&#8224;</body></html>}]
    set result [$doc asHTML -escapeNonASCII -htmlEntities]
    $doc delete
    set result
} {<html><body>&auml;&uuml;&bdquo;&#8223;&dagger;</body></html>}

test domDoc-1.3.1 {asHTML -htmlEntities} {
    set doc [dom parse -html {<html>&AMP;</html>}]
    set result [$doc asHTML -htmlEntities]
    $doc delete
    set result
} {<html>&amp;</html>}

test domDoc-1.3.2 {asHTML -htmlEntities} {
    set doc [dom parse -html "<html>\u205F\u200A</html>"]
    set result [$doc asHTML -htmlEntities]
    $doc delete
    set doc [dom parse -html "<html>\u205F</html>"]
    append result [$doc asHTML -htmlEntities]
    $doc delete
    set doc [dom parse -html "<html>\u200A</html>"]
    append result [$doc asHTML -htmlEntities]
    $doc delete    
    set result
} {<html>&ThickSpace;</html><html>&MediumSpace;</html><html>&hairsp;</html>}

test domDoc-1.3.3 {asHTML -htmlEntities} {
    set doc [dom parse -html "<html>fj</html>"]
    set result [$doc asHTML -htmlEntities]
    $doc delete
    set result
} {<html>&fjlig;</html>}

test domDoc-1.3.4 {asHTML -htmlEntities} {
    set doc [dom parse -html "<html>&NotLessLess;&ll;&nLt;\u226A\u20D2</html>"]
    set result [$doc asHTML -htmlEntities]
    $doc delete
    set result
} {<html>&nLtv;&ll;&nLt;&nLt;</html>}

test domDoc-1.3.3 {asHTML -htmlEntities} {
    set doc [dom parse -html "<html>&zopf;</html>"]
    set result [$doc asHTML -htmlEntities]
    $doc delete
    set result
} {<html>&zopf;</html>}

set doc [dom parse <root/>]

test domDoc-1.4 {asXML -doctypeDeclaration} {
    $doc asXML -doctypeDeclaration 1
} {<!DOCTYPE root>
<root/>
}

test domDoc-1.5 {asXML -doctypeDeclaration without boolean value (error)} {
    set errMsg ""
    catch {$doc asXML -doctypeDeclaration} errMsg
    set errMsg
} {-doctypeDeclaration must have a boolean value as argument}

test domDoc-1.6 {asXML -doctypeDeclaration 0} {
    $doc asXML -doctypeDeclaration 0
} {<root/>
}

$doc delete

test domDoc-1.7 {asXML -doctypeDeclaration} {
    set doc [dom parse {<!DOCTYPE root PUBLIC "-//foo//DTD bar x.y//EN" 
                                       "file:///boo.baz"><root/>}]
    set result [$doc asXML -doctypeDeclaration 1]
    $doc delete
    set result
} {<!DOCTYPE root PUBLIC "-//foo//DTD bar x.y//EN" "file:///boo.baz">
<root/>
}

test domDoc-1.8 {asXML -doctypeDeclaration} {
    set doc [dom parse {<!DOCTYPE root SYSTEM "file:///boo.baz"><root/>}]
    set result [$doc asXML -doctypeDeclaration 1]
    $doc delete
    set result
} {<!DOCTYPE root SYSTEM "file:///boo.baz">
<root/>
}   

test domDoc-1.9 {asXML -doctypeDeclaration} {
    set doc [dom parse {<!DOCTYPE root SYSTEM "file:///boo.baz"><root/>}]
    set result [$doc asXML -doctypeDeclaration true]
    $doc delete
    set result
} {<!DOCTYPE root SYSTEM "file:///boo.baz">
<root/>
}   

test domDoc-1.10 {asXML - unknown option} {
    set doc [dom parse {<!DOCTYPE root SYSTEM "file:///boo.baz"><root/>}]
    set errMsg ""
    catch {$doc asXML -fooOption 1} errMsg
    $doc delete
    set errMsg
} {bad option "-fooOption": must be -indent, -channel, -escapeNonASCII, -doctypeDeclaration, -xmlDeclaration, -encString, -escapeAllQuot, -indentAttrs, -nogtescape, -noEmptyElementTag, -escapeCR, or -escapeTab}

test domDoc-1.11 {asXML - non boolean value to -doctypeDeclaration} {
    set doc [dom parse {<!DOCTYPE root SYSTEM "file:///boo.baz"><root/>}]
    set errMsg ""
    catch {$doc asXML -doctypeDeclaration foo} errMsg
    $doc delete
    set errMsg
} {expected boolean value but got "foo"}

test domDoc-1.12 {asXML - shortened option} {
    set doc [dom parse {<!DOCTYPE root SYSTEM "file:///boo.baz"><root/>}]
    set result [$doc asXML -doctype 1]
    $doc delete
    set result
} {<!DOCTYPE root SYSTEM "file:///boo.baz">
<root/>
}   

test domDoc-1.13 {asHTML -doctypeDeclaration} {
    set doc [dom createDocument HTML]
    set result [$doc asHTML -doctypeDeclaration 1]
    $doc delete
    set result
} {<!DOCTYPE HTML>
<html></html>}

test domDoc-1.14 {asHTML -doctypeDeclaration} {
    set doc [dom parse {<!DOCTYPE HTML 
    PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
    "http://www.w3.org/TR/REC-html40/loose.dtd">
    <html><body><p>boo</p></body></html>}]
    set result [$doc asHTML -doctypeDeclaration 1]
    $doc delete
    set result
} {<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><p>boo</p></body></html>}

test domDoc-1.15 {asXML - processing-instruction without pi value} {
    set doc [dom parse {<doc><?p?></doc>}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc><?p ?></doc>}

test domDoc-1.16 {asXML - processing-instruction without pi value} {
    set doc [dom parse {<doc><?p ?></doc>}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc><?p ?></doc>}

test domDoc-1.17 {asHTML - content of script/style tags} {
    set doc [dom parse {
        <html><script>a &amp; b</script><style>foo &lt; bar</style></html>
    }]
    set result [$doc asHTML]
    $doc delete
    set result
} {<html>
<script>a & b</script><style>foo < bar</style>
</html>}

test domDoc-1.18 {asXML -escapeAllQuot} {
    set doc [dom parse {<doc>This is "strange"</doc>}]
    set result [$doc asXML -escapeAllQuot]
    $doc delete
    set result
} {<doc>This is &quot;strange&quot;</doc>
}

test domDoc-1.19 {asXML -escapeAllQuot} {
    set doc [dom parse {<doc>This is "strange"</doc>}]
    set result [$doc asXML]
    $doc delete
    set result
} {<doc>This is "strange"</doc>
}

test domDoc-1.20 {asXML - indentation of comments} {
    set doc [dom parse {<doc>
<!--Comment 1-->
<e1/>
<!--Comment 2--></doc>}]
    set result [$doc asXML -indent 4]
    $doc delete
    set result
} {<doc>
    <!--Comment 1-->
    <e1/>
    <!--Comment 2-->
</doc>
}

test domDoc-1.21 {asXML -indentAttrs} {
    set doc [dom parse {<Element attr1="val1" attr2="val2"/>}]
    set result [$doc asXML -indentAttrs 4]
    $doc delete
    set result
} {<Element
    attr1="val1"
    attr2="val2"/>
}

test domDoc-1.22 {asXML} {
    set doc [dom createDocument doc]
    set result [$doc asXML]
    $doc delete
    set result
} {<doc/>
}

test domDoc-1.23 {asXML -xmlDeclaration} {
    set doc [dom createDocument doc]
    set result [$doc asXML -xmlDeclaration 1]
    $doc delete
    set result
} {<?xml version="1.0"?>
<doc/>
}

test domDoc-1.23 {asXML -xmlDeclaration} {
    set doc [dom createDocument doc]
    set result [$doc asXML -xmlDeclaration 1]
    $doc delete
    set result
} {<?xml version="1.0"?>
<doc/>
}

test domDoc-1.24 {asXML just -encString without -xmlDeclaration} {
    set doc [dom createDocument doc]
    set result [$doc asXML -encString foo]
    $doc delete
    set result
} {<doc/>
}

test domDoc-1.25 {asXML -xmlDeclaration -encString} {
    set doc [dom createDocument doc]
    set result [$doc asXML -xmlDeclaration 1 -encString foo]
    $doc delete
    set result
} {<?xml version="1.0" encoding="foo"?>
<doc/>
} 

test domDoc-1.26 {asXML -xmlDeclaration, encoding set by encoding method} {
    set doc [dom createDocument doc]
    $doc encoding "foo"
    set result [$doc asXML -xmlDeclaration 1]
    $doc delete
    set result
} {<?xml version="1.0" encoding="foo"?>
<doc/>
}    

test domDoc-1.27 {asXML -xmlDeclaration -encString} {
    set doc [dom createDocument doc]
    set result [catch {
        [$doc asXML -xmlDeclaration 1 -encString foo \
             -encString bar -wrongOption]
    }]
    $doc delete
    set result
} 1 

test domDoc-1.28 {asXML -xmlDeclaration not xml compliant -encString} {
    set doc [dom createDocument doc]
    set result [$doc asXML -xmlDeclaration 1 -encString 1\u2345]
    $doc delete
    set result
} [subst -nocommands -novariables {<?xml version="1.0" encoding="1\u2345"?>
<doc/>
}]

test domDoc-1.29 {asXML -nogtescape} {
    set doc [dom parse {<doc attr="foo>bar">></doc>}]
    set result [$doc asXML -nogtescape -indent none]
    $doc delete
    set result
} {<doc attr="foo>bar">></doc>}

test domDoc-1.30 {asXML -noEmptyElementTag} {
    set doc [dom parse {<doc><elm/></doc>}]
    set result [$doc asXML -noEmptyElementTag -indent none]
    $doc delete
    set result
} {<doc><elm></elm></doc>}

test domDoc-1.31 {asXML '"' in attribute value} {
    # emacs: "
    set doc [dom createDocument doc]
    set root [$doc documentElement]
    $root setAttribute attr "foo\"bar"
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc attr="foo&quot;bar"/>}

test domDoc-1.32 {asXML -indent tabs} {
    set doc [dom parse {<doc><a><b/></a></doc>}]
    set result [$doc asXML -indent tabs]
    $doc delete
    set result
} "<doc>\n\t<a>\n\t\t<b/>\n\t</a>\n</doc>\n"

test domDoc-1.33 {asXML -indent tabs} {
    set doc [dom parse {<doc><a><b/></a><c><d><f/></d></c><g/></doc>}]
    set result [$doc asXML -indent tabs]
    $doc delete
    set result
} "<doc>\n\t<a>\n\t\t<b/>\n\t</a>\n\t<c>\n\t\t<d>\n\t\t\t<f/>\n\t\t</d>\n\t</c>\n\t<g/>\n</doc>\n"

test domDoc-1.34 {asXML -indent tabs -noEmptyElementTag} {
    set doc [dom parse {<doc><a><b/></a><c><d><f/></d></c><g/></doc>}]
    set result [$doc asXML -indent tabs -noEmptyElementTag]
    $doc delete
    set result
} "<doc>\n\t<a>\n\t\t<b></b>\n\t</a>\n\t<c>\n\t\t<d>\n\t\t\t<f></f>\n\t\t</d>\n\t</c>\n\t<g></g>\n</doc>\n"

test domDoc-1.35 {asXML -indent tabs -indentAttrs tabs} {
    set doc [dom parse {<doc><a a1="a1" a2="a2"><b/></a><c><d a1="a1" a2="a2"><f/></d></c><g/></doc>}]
    set result [$doc asXML -indent tabs -indentAttrs tabs]
    $doc delete
    set result
} "<doc>\n\t<a\n\t\ta1=\"a1\"\n\t\ta2=\"a2\">\n\t\t<b/>\n\t</a>\n\t<c>\n\t\t<d\n\t\t\ta1=\"a1\"\n\t\t\ta2=\"a2\">\n\t\t\t<f/>\n\t\t</d>\n\t</c>\n\t<g/>\n</doc>\n"

test domDoc-1.36 {asXML -indent tabs -indentAttrs <num>} {
    set doc [dom parse {<doc><a a1="a1" a2="a2"><b/></a><c><d a1="a1" a2="a2"><f/></d></c><g/></doc>}]
    set result [$doc asXML -indent tabs -indentAttrs 2]
    $doc delete
    set result
} "<doc>\n\t<a\n\t  a1=\"a1\"\n\t  a2=\"a2\">\n\t\t<b/>\n\t</a>\n\t<c>\n\t\t<d\n\t\t  a1=\"a1\"\n\t\t  a2=\"a2\">\n\t\t\t<f/>\n\t\t</d>\n\t</c>\n\t<g/>\n</doc>\n"

test domDoc-1.37 {asHTML -onlyContents} {
    set doc [dom parse {<html><body><p>boo</p></body></html>}]
    set result [[$doc documentElement] asHTML -onlyContents]
    $doc delete
    set result
} {<body><p>boo</p></body>}

test domDoc-1.38 {asHTML -breakLines} {
    set doc [dom parse {<html><body><p>boo</p></body></html>}]
    set result [$doc asHTML -breakLines]
    $doc delete
    set result
} {<html
><body
><p
>boo</p></body></html>}

set doc [dom parse <root/>]

test domDoc-2.1 {publicId - no publicId there} {
    $doc publicId
} {}

test domDoc-2.2 {systemId - no systemId there} {
    $doc systemId
} {}

$doc delete
set doc [dom parse {<!DOCTYPE root PUBLIC "-//foo//DTD bar x.y//EN" "file:///boo.baz"><root/>}]

test domDoc-2.3 {publicId from parsed document} {
    $doc publicId
} {-//foo//DTD bar x.y//EN}

test domDoc-2.4 {systemId from parsed document} {
    $doc systemId
} {file:///boo.baz}

$doc delete
set doc [dom parse {<!DOCTYPE root SYSTEM "file:///boo.baz"><root/>}]

test domDoc-2.5 {publicId but document has only SYSTEM} {
    $doc publicId
} {}

test domDoc-2.6 {systemId, document has only SYSTEM} {
    $doc systemId
} {file:///boo.baz}

test domDoc-2.7 {publicId - set public identifier} {
    set result [$doc publicId "file:///woo.hoo"]
    append result " [$doc publicId]"
} { file:///woo.hoo} 

test domDoc-2.8 {publicId - set public identifier} {
    $doc publicId "http://www.tdom.org"
    $doc asXML -indent no -doctypeDeclaration 1
} {<!DOCTYPE root PUBLIC "http://www.tdom.org" "file:///boo.baz">
<root/>}

test domDoc-2.9 {systemId - set system identifier} {
    set result [$doc systemId "file:///woo.hoo"]
    append result " [$doc systemId]"
} {file:///boo.baz file:///woo.hoo}

test domDoc-2.10 {systemId - set system identifier} {
    $doc systemId "file:///whooze.moo"
    $doc asXML -indent no -doctypeDeclaration 1
} {<!DOCTYPE root PUBLIC "http://www.tdom.org" "file:///whooze.moo">
<root/>}

test domDoc-2.11 {publicId - set to empty string} {
    $doc publicId ""
    $doc asXML -indent no -doctypeDeclaration 1
} {<!DOCTYPE root SYSTEM "file:///whooze.moo">
<root/>}

test domDoc-2.12 {systemId - set to empty string} {
    $doc systemId ""
    $doc asXML -indent no -doctypeDeclaration 1
} {<!DOCTYPE root>
<root/>}

$doc delete


set doc [dom parse <root/>]

set xslt1 {
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:param name="param1" select="'param1Default'"/>
    <xsl:param name="param2" select="'param2Default'"/>
    <xsl:param name="param3" select="'param3Default'"/>
    <xsl:template match="/">
        <xsl:value-of select="$param1"/>
        <xsl:text> </xsl:text>
        <xsl:value-of select="$param2"/>
        <xsl:text> </xsl:text>
        <xsl:value-of select="$param3"/>
        <xsl:text> </xsl:text>
    </xsl:template>
</xsl:stylesheet>}

test domDoc-3.1 {toXSLTcmd} {
    set xslt [dom parse -keepEmpties $xslt1]
    set xsltCmd [$xslt toXSLTcmd]
    
    $xsltCmd -parameters {param2 newValue param3 "this Value"} $doc resultDoc
    set result [$resultDoc asXML -indent none]
    $resultDoc delete
    $xsltCmd -parameters {param1 "that Value"} $doc resultDoc
    append result [$resultDoc asXML -indent none]
    $resultDoc delete
    $xsltCmd -parameters {param3 "another" param1 "and this"} $doc resultDoc
    append result [$resultDoc asXML -indent none]
    $resultDoc delete
    rename $xsltCmd {}
    set result
} {param1Default newValue this Value that Value param2Default param3Default and this param2Default another }

set xslt2 {
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="/">
        <xsl:text>dummy result</xsl:text>
        <xsl:message>This is from xsl:message</xsl:message>
    </xsl:template>
</xsl:stylesheet>}

proc msgCmd1 {msg terminate} {
    global result
    append result "msgCmd1: $msg "
}

proc msgCmd2 {msg terminate} {
    global result
    append result "msgCmd2: $msg"
}

test domDoc-3.2 {toXSLTcmd} {
    set xslt [dom parse -keepEmpties $xslt2]
    set xsltCmd [$xslt toXSLTcmd]

    set result ""
    $xsltCmd -xsltmessagecmd msgCmd1 $doc resultDoc
    $resultDoc delete
    $xsltCmd -xsltmessagecmd msgCmd2 $doc resultDoc
    $resultDoc delete
    rename $xsltCmd {}
    set result
} {msgCmd1: This is from xsl:message msgCmd2: This is from xsl:message}

test domDoc-3.3 {toXSLTcmd} {
    set xslt [dom parse -keepEmpties $xslt1]
    set xsltCmd [$xslt toXSLTcmd]

    set result [catch {$xsltCmd -bogusOption foo $doc resultDoc} errMsg]
    lappend result $errMsg
    lappend result [catch {$xsltCmd $doc resultDoc}]
    lappend result [$resultDoc asXML -indent none]
    $resultDoc delete
    rename $xsltCmd {}
    set result
} {1 {bad option "-bogusOption": must be -parameters, -ignoreUndeclaredParameters, -maxApplyDepth, or -xsltmessagecmd} 0 {param1Default param2Default param3Default }}

test domDoc-3.4 {toXSLTcmd} {
    set xslt [dom parse -keepEmpties $xslt1]
    set xsltCmd [$xslt toXSLTcmd]

    set result [catch {$xsltCmd -xsltmessagecmd msgCmd1} errMsg]
    rename $xsltCmd {}
    lappend result $errMsg
} {1 {wrong # args: should be "?-parameters parameterList? ?-ignoreUndeclaredParameters? ?-maxApplyDepth int? ?-xsltmessagecmd cmd? <xmlDocObj> ?objVar?"}}

test domDoc-3.5 {toXSLTcmd} {
    set xslt [dom parse -keepEmpties $xslt1]
    set xsltCmd [$xslt toXSLTcmd]

    set result [catch {$xsltCmd $doc resultDoc bogus} errMsg]
    rename $xsltCmd {}
    lappend result $errMsg
} {1 {wrong # args: should be "?-parameters parameterList? ?-ignoreUndeclaredParameters? ?-maxApplyDepth int? ?-xsltmessagecmd cmd? <xmlDocObj> ?objVar?"}}

test domDoc-3.6 {toXSLTcmd} {
    set xslt [dom parse -keepEmpties $xslt1]
    set xsltCmd [$xslt toXSLTcmd]

    set result [catch {$xsltCmd -parameters {param1 foo} -parameters {param2 foo} $doc resultDoc} errMsg]
    rename $xsltCmd {}
    lappend result $errMsg
} {1 {only one -parameters option allowed}}

test domDoc-3.7 {toXSLTcmd} {
    set xslt [dom parse -keepEmpties $xslt1]
    set xsltCmd [$xslt toXSLTcmd]

    set result [catch {$xsltCmd}]
    $xsltCmd delete
    set result
} {1}

test domDoc-3.8 {toXSLTcmd} {
    set xslt [dom parse -keepEmpties $xslt1]
    set xsltCmd [$xslt toXSLTcmd]

    set result [catch {$xsltCmd delete bogus}]
    $xsltCmd delete
    set result 
} {1}

test domDoc-3.9 {toXSLTcmd} {
    set xslt [dom parse -keepEmpties $xslt1]
    set xsltCmd [$xslt toXSLTcmd]

    set result [catch {$xsltCmd transform} errMsg]
    $xsltCmd delete
    set result
} {1}

test domDoc-3.10 {toXSLTcmd} {
    set xslt [dom parse -keepEmpties $xslt1]
    set xsltCmd [$xslt toXSLTcmd]
    $xsltCmd transform $doc resultDoc              
    set result [$resultDoc asXML -indent none]
    $resultDoc delete
    $xsltCmd delete
    set result
} {param1Default param2Default param3Default }

set xslt3 {<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0">
    <xsl:output cdata-section-elements="foo
    doc b   bar"/>
    <xsl:template match="/">
        <doc>mixed element <b>this is</b> more text</doc>
    </xsl:template>
</xsl:stylesheet>}

test domDoc-3.11 {toXSLTcmd} {
    set xslt [dom parse -keepEmpties $xslt3]
    set xsltCmd [$xslt toXSLTcmd]
    set result [list]
    for {set x 0} {$x < 2} {incr x} {
        $xsltCmd $doc resultDoc
        lappend result [lsort [$resultDoc cdataSectionElements *]]
        lappend result [$resultDoc asXML -indent none]
        $resultDoc delete
    }
    $xsltCmd delete
    set result
} {{b bar doc foo} {<doc><![CDATA[mixed element ]]><b><![CDATA[this is]]></b><![CDATA[ more text]]></doc>} {b bar doc foo} {<doc><![CDATA[mixed element ]]><b><![CDATA[this is]]></b><![CDATA[ more text]]></doc>}}

$doc delete

test domDoc-4.1 {asText - syntax check} {
    dom parse <root/> doc
    set result [catch {$doc asText foo}]
    $doc delete
    set result
} {1}

test domDoc-4.2 {asText} {
    dom parse {<root>pcdata <child>foo bar grill</child></root>} doc
    set result [$doc asText]
    $doc delete
    set result
} {pcdata foo bar grill}

test domDoc-4.3 {asText} {
    dom parse {<root>pcdata <![CDATA[<greeting>Hello, world!</greeting>]]>
        more pcdata</root>} doc
    set result [$doc asText]
    $doc delete
    set result
} {pcdata <greeting>Hello, world!</greeting>
        more pcdata}

test domDoc-4.4 {asText} {
    dom parse {<root>pcdata</root>} doc
    $doc documentElement root
    set newCDATAnode \
        [$doc createCDATASection "<greeting>Hello, world!</greeting>"]
    $root appendChild $newCDATAnode
    set result [$doc asText]
    $doc delete
    set result
} {pcdata}

test domDoc-4.5 {asText} {
    dom parse {<root>encoded chars: &gt; &lt; &amp; &quot; &apos;</root>} doc
    set result [$doc asText]
    $doc delete
    set result
} {encoded chars: > < & " '} 
# emacs: "

test domDoc-5.1 {normalize} {
    set doc [dom parse <root><child>text</child></root>]
    $doc documentElement root
    set cdataNode [$doc createCDATASection "cdata section text"]
    set child [$root firstChild]
    $child appendChild $cdataNode
    $doc normalize
    set result [llength [$child childNodes]]
    lappend result [[$child firstChild] data]
    $doc delete
    set result
} {2 text}

test domDoc-5.2 {normalize} {
    set doc [dom parse <root><child>text</child></root>]
    $doc documentElement root
    set cdataNode [$doc createCDATASection "cdata section text"]
    set child [$root firstChild]
    $child appendChild $cdataNode
    $doc normalize -forXPath
    set result [llength [$child childNodes]]
    lappend result [[$child firstChild] data]
    $doc delete
    set result
} {1 {textcdata section text}}

test domDoc-5.3 {normalize} {
    set doc [dom parse <root><child/></root>]
    $doc documentElement root
    set cdataNode [$doc createCDATASection "cdata section text"]
    set textNode [$doc createTextNode text]
    set child [$root firstChild]
    $child appendChild $cdataNode
    $child appendChild $textNode
    set result [llength [$child childNodes]]
    $doc normalize -forXPath
    lappend result [llength [$child childNodes]]
    lappend result [[$child firstChild] data]
    $doc delete
    set result
} {2 1 {cdata section texttext}}

test domDoc-5.4 {normalize} {
    set doc [dom parse <root><child/></root>]
    $doc documentElement root
    set cdataNode [$doc createCDATASection "cdata section text"]
    set child [$root firstChild]
    $child appendChild $cdataNode
    $doc normalize
    set result [$cdataNode nodeType]
    $doc normalize -forXPath
    lappend result [$cdataNode nodeType]
    $doc delete
    set result
} {CDATA_SECTION_NODE TEXT_NODE}

test domDoc-5.5 {normalize} {
    set doc [dom parse <root><child/></root>]
    $doc documentElement root
    set textNode [$doc createTextNode ""]
    set child [$root firstChild]
    $child appendChild $textNode
    set result [llength [$child childNodes]]
    $doc normalize
    lappend result [llength [$child childNodes]]
    $doc delete
    set result
} {1 0}

test domDoc-5.6 {normalize} {
    set doc [dom parse <root><child/></root>]
    $doc documentElement root
    set cdataNode [$doc createCDATASection ""]
    set child [$root firstChild]
    $child appendChild $cdataNode
    $doc normalize
    set result [llength [$child childNodes]]
    $doc normalize -forXPath
    lappend result [llength [$child childNodes]]
    $doc delete
    set result
} {1 0}

test domDoc-6.1 {nodeType} {
    set doc [dom parse <root/>]
    set result [$doc nodeType]
    $doc delete
    set result
} {DOCUMENT_NODE}

test domDoc-6.2 {nodeType} {
    set doc [dom parse <root/>]
    set result [catch {$doc nodeType foo}]
    $doc delete
    set result
} {1}

test domDoc-7.1 {insertBefore} {
    set doc [dom parse {<!-- Comment --><root/>}]
    set root [$doc documentElement]
    set newPI [$doc createProcessingInstruction myPI pivalue]
    $doc insertBefore $newPI $root
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<!-- Comment --><?myPI pivalue?><root/>}

test domDoc-7.2 {insertBefore} {
    set doc [dom parse {<!-- Comment --><root/>}]
    set newPI [$doc createProcessingInstruction myPI pivalue]
    $doc insertBefore $newPI ""
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<!-- Comment --><root/><?myPI pivalue?>}

test domDoc-7.3 {insertBefore} {
    set doc [dom parse {<!-- Comment --><root><child/></root>}]
    set newPI [$doc createProcessingInstruction myPI pivalue]
    set root [$doc documentElement]
    set child [$root firstChild]
    set result [catch {$doc insertBefore $newPI $child} errMsg]
    lappend result $errMsg
    $doc delete
    set result
} {1 NOT_FOUND_ERR}

namespace eval nodeCmds {
    dom createNodeCmd elementNode e1
    dom createNodeCmd elementNode e2
    dom createNodeCmd commentNode c
    dom createNodeCmd textNode    t
    dom createNodeCmd cdataNode   cdata
    dom createNodeCmd piNode      pi
    dom createNodeCmd parserNode  parser
}

test domDoc-8.1 {insertBeforeFromScript} {
    set doc [dom parse {<root><child/></root>}]
    $doc documentElement root
    $doc insertBeforeFromScript {
        nodeCmds::e1
    } $root
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<e1/><root><child/></root>}

test domDoc-8.2 {insertBeforeFromScript} {
    set doc [dom parse {<root><child/></root>}]
    $doc insertBeforeFromScript {
        nodeCmds::e1
    } ""
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<root><child/></root><e1/>}

test domDoc-8.3 {insertBeforeFromScript} {
    set doc [dom parse {<root><child/></root>}]
    $doc documentElement root
    set result [catch {$root insertBeforeFromScript {
        nodeCmds::e1
        nodeCmds::e1 {
            # This is intentionally wrong
            set foo 1 + 1
        }
    } $root}]
    lappend result [$doc asXML -indent none]
    $doc delete
    set result
} {1 <root><child/></root>}

test domDoc-9.1 {replaceChild} {
    set doc [dom parse {<!-- Comment --><root><child/></root>}]
    set root [$doc documentElement]
    set newNode [$doc createElement newNode]
    $doc replaceChild $newNode $root
    set result [$doc asXML -indent none]
    lappend result [[$doc documentElement] nodeName]
    $doc delete
    set result
} {<!-- Comment --><newNode/> newNode}

set getElementByIdSetup {    
    set doc [dom parse {
        <!DOCTYPE root [
                        <!ELEMENT root (elem*)>
                        <!ELEMENT elem ANY>
                        <!ATTLIST elem
                        id      ID      #IMPLIED
                        name    CDATA   #IMPLIED>
                       ]>
        <root>
        <elem id="7" name="this"/>
        <elem id="4a" name="that"/>
        <elem name="and"/>
        <elem id="a2" name="this"/>
        </root>}]
}

test domDoc-10.1 {getElementById} -setup $getElementByIdSetup -body {
    set result [[$doc getElementById "4a"] @name]
    lappend result [$doc getElementById "dontexists"]
} -cleanup {
    $doc delete
} -result {that {}}

test domDoc-10.2 {getElementById - only IDs at parsing time will be found} \
    -setup $getElementByIdSetup -body {
        set root [$doc documentElement]
        set elemNode [$root selectNodes {elem[3]}]
        if {[$elemNode hasAttribute id]} {
            error "error in the test code"
        }
        $elemNode setAttribute id "new"
        $doc getElementById "new"
    } -cleanup {
        $doc delete
    } -result {}

test domDoc-10.3 {getElementById} -setup $getElementByIdSetup -body {
    set root [$doc documentElement]
    set elemNode [$root selectNodes {elem[2]}]
    if {![$elemNode hasAttribute id]} {
        error "error in the test code"
    }
    $elemNode setAttribute id "new"
    [$doc getElementById "new"] getAttribute name
} -cleanup {
    $doc delete
} -result that

test domDoc-10.4 {getElementById} -setup $getElementByIdSetup -body {
    set root [$doc documentElement]
    set elemNode [$root selectNodes {elem[2]}]
    if {![$elemNode hasAttribute id]} {
        error "error in the test code"
    }
    $root removeChild $elemNode
    [$doc getElementById "4a"] getAttribute name
} -cleanup {
    $doc delete
} -result that

test domDoc-10.5 {getElementById} -setup $getElementByIdSetup -body {
    set root [$doc documentElement]
    set elemNode [$root selectNodes {elem[2]}]
    if {![$elemNode hasAttribute id]} {
        error "error in the test code"
    }
    $elemNode removeAttribute id
    $doc getElementById "4a"
} -cleanup {
    $doc delete
} -result {}

test domDoc-11.1 {firstChild} {
    set doc [dom createDocumentNode]
    set result [$doc firstChild]
    $doc delete
    set result
} {}

test domDoc-11.2 {firstChild} {
    set doc [dom parse <root/>]
    set result [[$doc firstChild] nodeName]
    $doc delete
    set result
} {root}

test domDoc-11.3 {firstChild} {
    set doc [dom parse {<?beforeRoot this?><root/><?afterRoot that?>}]
    set result [[$doc firstChild] nodeName]
    $doc delete
    set result
} {beforeRoot}

test domDoc-11.4 {firstChild} {
    set doc [dom parse {<root/>}]
    set node [$doc firstChild]
    set newNode [$doc createElement newNode]
    $doc insertBefore $newNode $node
    set result [[$doc firstChild] nodeName]
    $doc delete
    set result
} {newNode}

test domDoc-11.5 {Delete top level node} {
    set doc [dom parse {<!---comment on top level--><root/>}]
    [$doc firstChild] delete
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<root/>}

test domDoc-11.6 {Delete top level node} {
    set doc [dom parse {<!---comment on top level--><root/>}]
    [$doc documentElement] delete
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<!---comment on top level-->}

test domDoc-12.1 {lastChild} {
    set doc [dom createDocumentNode]
    set result [$doc lastChild]
    $doc delete
    set result
} {}

test domDoc-12.2 {lastChild} {
    set doc [dom parse <root/>]
    set result [[$doc lastChild] nodeName]
    $doc delete
    set result
} {root}

test domDoc-12.3 {lastChild} {
    set doc [dom parse {<?beforeRoot this?><root/><?afterRoot that?>}]
    set result [[$doc lastChild] nodeName]
    $doc delete
    set result
} {afterRoot}

test domDoc-12.4 {lastChild} {
    set doc [dom parse {<root/>}]
    set newNode [$doc createElement newNode]
    $doc appendChild $newNode
    set result [[$doc lastChild] nodeName]
    lappend result [[$doc lastChild] parentNode]
    $doc delete
    set result
} {newNode {}}

test domDoc-13.1 {appendChild} {
    set doc [dom parse {<root/>}]
    set newNode [$doc createElement newNode]
    $doc appendChild $newNode
    set newNode [$doc createComment "a comment"]
    $doc appendChild $newNode
    set newNode [$doc createProcessingInstruction this that]
    $doc appendChild $newNode
    set newNode [$doc createTextNode "text"]
    $doc appendChild $newNode
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<root/><newNode/><!--a comment--><?this that?>text}

test domDoc-13.2 {appendChild} {
    set doc [dom createDocumentNode]
    set newNode [$doc createElement newNode]
    $doc appendChild $newNode
    set result [[$doc documentElement] nodeName]
    $doc delete
    set result
} {newNode}

test domDoc-13.3 {appendChild} {
    set doc [dom createDocumentNode]
    set newNode [$doc createElement newNode]
    $doc appendChild $newNode
    set result [[$doc documentElement] parentNode]
    $doc delete
    set result
} {}

test domDoc-14.1 {removeChild} {
    set doc [dom parse {<root/>}]
    $doc removeChild [$doc firstChild]
    set result [$doc documentElement]
    $doc delete
    set result
} {}

test domDoc-14.2 {removeChild} {
    set doc [dom parse {<!---comment on top level--><root/>}]
    $doc removeChild [$doc firstChild]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<root/>}

test domDoc-14.3 {removeChild} {
    set doc [dom createDocumentNode]
    set result [catch {$doc removeChild [$doc firstChild]}]
    $doc delete
    set result
} {1}

test domDoc-15.1 {hasChildNodes} {
    set doc [dom createDocumentNode]
    set result [$doc hasChildNodes]
    set newNode [$doc createElement newNode]
    $doc appendChild $newNode
    lappend result [$doc hasChildNodes]
    $doc delete
    set result
} {0 1}

test domDoc-16.1 {childNodes} {
    set doc [dom parse {<?beforeRoot this?><root/><?afterRoot that?>}]
    set result {}
    foreach node [$doc childNodes] {
        lappend result [$node nodeName]
    }
    $doc delete
    set result
} {beforeRoot root afterRoot}

test domDoc-17.1 {ownerDocument} {
    set doc [dom parse <root/>]
    set result [expr {$doc == [$doc ownerDocument]}]
    $doc delete
    set result
} {1}

test domDoc-18.1 {appendFromList} {
    set doc [dom createDocumentNode]
    $doc appendFromList {elem {} {}}
    set node [$doc documentElement]
    set result [list [$node nodeName] [$node parentNode]]
    $doc delete
    set result
} {elem {}}

test domDoc-19.1 {appendXML} {
    set doc [dom createDocumentNode]
    $doc appendXML <test>foo<child><childchild>text</childchild></child></test>
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<test>foo<child><childchild>text</childchild></child></test>}

test domDoc-19.2 {appendXML} {
    set doc [dom createDocumentNode]
    $doc appendXML <test>foo<child><childchild>text</childchild></child></test>
    set result [[$doc documentElement] nodeName]
    lappend result [[$doc documentElement] parentNode]
    lappend result [expr {$doc == [[$doc documentElement] ownerDocument]}]
    $doc delete
    set result
} {test {} 1}

test domDoc-19.3 {appendXML} {
    set doc [dom createDocument foo]
    $doc appendXML <test>foo<child><childchild>text</childchild></child></test>
    set result [[$doc documentElement] nodeName]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<foo/><test>foo<child><childchild>text</childchild></child></test>}
    
test domDoc-19.4 {appendXML XML namespaces} {
    dom createDocumentNS ns:a docroot doc
    $doc documentElement root
    $root setAttributeNS "" xmlns:b "ns:b" "" xmlns:c "ns:c"
    $root appendXML {<person xmlns="ns:c"><name>John</name></person>}
    $doc selectNodesNamespaces "a ns:a b ns:b c ns:c"
    set name [$doc selectNodes string(a:docroot/c:person/c:name)]
    $doc delete
    set name
} {John}

test domDoc-19.5 {appendXML XML namespaces} {
    dom createDocumentNS ns:a docroot doc
    $doc documentElement root
    $root setAttributeNS "" xmlns:b "ns:b" "" xmlns:c "ns:c"
    $root appendXML {<person xmlns="ns:c" xmlns:d="ns:a"><d:name>John</d:name></person>}
    $doc selectNodesNamespaces "a ns:a b ns:b c ns:c"
    set name [$doc selectNodes string(a:docroot/c:person/a:name)]
    $doc delete
    set name
} {John}

test domDoc-19.6 {appendXML XML namespaces} {
    dom createDocumentNS ns:c docroot doc
    $doc documentElement root
    $root setAttributeNS "" xmlns:b "ns:b" "" xmlns:a "ns:a"
    $root appendXML {<person xmlns="ns:c"><name>Eve</name></person>}
    $doc selectNodesNamespaces "a ns:a b ns:b c ns:c"
    set name [$doc selectNodes string(c:docroot/c:person/c:name)]
    $doc delete
    set name
} {Eve}

test domDoc-19.7 {appendXML XML namespaces} {
    dom createDocument docroot doc
    $doc documentElement root
    $root setAttributeNS "" xmlns:b "ns:b" "" xmlns:c "ns:c"
    $root appendXML {<person xmlns="ns:c"><name>Eve</name></person>}
    $doc selectNodesNamespaces "foo ns:c"
    set name [$doc selectNodes string(docroot/foo:person/foo:name)]
    $doc delete
    set name
} {Eve}

test domDoc-20.1 {selectNodes} {
    set doc [dom parse {<root><child id="1"/><child id="2"/></root>}]
    set result [[$doc selectNodes {root/child[2]}] getAttribute id]
    $doc delete
    set result
} {2}

test domDoc-20.2 {selectNodes} {
    set doc [dom parse {<root><child id="1"/><child id="2"/></root>}]
    set result [[$doc selectNodes {/root/child[2]}] getAttribute id]
    $doc delete
    set result
} {2}

test domDoc-20.3 {selectNodes} {
    set doc [dom parse {<!-- Comment --><root/><?piAfterRoot value?>}]
    set result [list]
    foreach node [$doc selectNodes *] {
        lappend result [$node nodeName]
    }
    set result
} {root}

test domDoc-20.4 {selectNodes} {
    set doc [dom parse {<!-- Comment --><root/><?piAfterRoot value?>}]
    set result [list]
    foreach node [$doc selectNodes node()] {
        lappend result [$node nodeType]
    }
    set result
} {COMMENT_NODE ELEMENT_NODE PROCESSING_INSTRUCTION_NODE}

test domDoc-20.5 {selectNodes with -namespaces option} {
    set doc [dom createDocumentNS "http://tdom.org" tdom:doc]
    set node [$doc selectNodes \
                  -namespaces {tdom http://tdom.org} \
                  tdom:doc]
    set result [$node nodeName]
    set node [$doc selectNodes \
                  -namespaces {myPrefix http://tdom.org} \
                  myPrefix:doc]
    lappend result [$node nodeName]
    lappend result [$doc selectNodes -namespaces {} doc typeVar]
    lappend result $typeVar
    $doc delete
    set result
} [list tdom:doc tdom:doc "" empty]

test domDoc-20.6 {selectNodes with -namespaces option} {
    set doc [dom createDocumentNS "http://tdom.org" tdom:doc]
    set node [$doc selectNodes \
                  -namespaces {foo bar} \
                  -namespaces {a b c d} \
                  -namespaces {tdom http://tdom.org} \
                  tdom:doc]
    set result [$node nodeName]
    set node [$doc selectNodes \
                  -namespaces {myPrefix http://tdom.org} \
                  myPrefix:doc]
    lappend result [$node nodeName]
    lappend result [$doc selectNodes -namespaces {} doc typeVar]
    lappend result $typeVar
    $doc delete
    set result
} [list tdom:doc tdom:doc "" empty]

test domDoc-20.7 {selectNodes with -namespaces option} {
    set doc [dom createDocumentNS "http://tdom.org" tdom:doc]
    catch {set node [$doc selectNodes \
                         -namespaces {foo bar} \
                         -namespaces {a b c d} \
                         -namespaces {wrong_not_pair} \
                         tdom:doc]} errMsg
    $doc delete
    set errMsg
} {The "-namespaces" option requires a 'prefix namespace' pairs list as argument}

test domDoc-20.8 {selectNodes with -list option} {
    set doc [dom parse {
        <doc>
        <product><descshort>one</descshort></product>
        <product><descshort>two</descshort></product>
        <product><descshort>three four</descshort></product>
        </doc>
    }]
    set result [$doc selectNodes -list {
        doc/product/descshort
        string()
    }]
    $doc delete
    set result
} {one two {three four}}

test domDoc-20.9 {selectNodes - type result} {
    set doc [dom parse {
        <doc>
        <product><descshort>one</descshort></product>
        <product><descshort></descshort></product>
        <product></product>
        </doc>
    }]
    set result ""
    lappend result [$doc selectNodes {string(doc/product[1]/descshort)} typeVar]
    lappend result $typeVar
    lappend result [$doc selectNodes {string(doc/product[2]/descshort)} typeVar]
    lappend result $typeVar
    lappend result [$doc selectNodes {string(doc/product[3]/descshort)} typeVar]
    lappend result $typeVar
    $doc delete
    set result
} {one string {} string {} string}
             
test domDoc-20.10 {selectNodes with -list option} {
    set doc [dom parse {
        <doc>
        <product><descshort>one</descshort></product>
        <product><descshort>two</descshort></product>
        <product><descshort>three four</descshort></product>
        </doc>
    }]
    set result [$doc selectNodes -list {
        doc/product/descshort
        string()
    } typeVar]
    $doc delete
    lappend result $typeVar
} {one two {three four} string}

test domDoc-20.11 {selectNodes with -list option} {
    set doc [dom parse {
        <doc>
        <product><descshort>one</descshort></product>
        <product><descshort>two</descshort></product>
        <product><descshort>three four</descshort></product>
        </doc>
    }]
    set result [$doc selectNodes -list {
        doc/product/dontexists
        string()
    } typeVar]
    $doc delete
    list $result $typeVar
} {{} empty}

test domDoc-21.1 {baseURI} {
    set doc [dom createDocumentNode]
    set result [$doc baseURI]
    $doc delete
    set result
} {}

test domDoc-21.2 {baseURI} {
    set doc [dom parse -baseurl file://foo <root/>]
    set result [$doc baseURI]
    $doc baseURI http://that.this
    lappend result [$doc baseURI]
    $doc delete
    set result
} {file://foo http://that.this}

namespace eval nodeCmds {
    dom createNodeCmd elementNode e1
    dom createNodeCmd elementNode e2
    dom createNodeCmd commentNode c
    dom createNodeCmd textNode    t
    dom createNodeCmd cdataNode   cdata
    dom createNodeCmd piNode      pi
    dom createNodeCmd parserNode  parser
}
test domDoc-22.1 {appendFromScript} {
    set doc [dom createDocumentNode]
    $doc appendFromScript nodeCmds::e1
    set result [$doc asXML -indent none]
    lappend result [[$doc documentElement] nodeName]
    $doc delete
    set result
} {<e1/> e1}

test domDoc-22.2 {appendFromScript} {
    set doc [dom parse <root/>]
    $doc appendFromScript {
        nodeCmds::e1
        nodeCmds::e2
    }
    # namespace eval nodeCmds {
    #     $doc appendFromScript {
    #         e1
    #         e2
    #     }
    # }
    set result [$doc asXML -indent none]
    foreach node [$doc selectNodes *] {
        lappend result [$node parentNode]
        lappend result [expr {$doc == [$node ownerDocument]}]
    }
    $doc delete
    set result
} {<root/><e1/><e2/> {} 1 {} 1 {} 1}

test domDoc-22.3 {appendFromScript} {
    set doc [dom createDocumentNode]
    set nrOfNodeCmdsBefore [info commands domNode*]
    $doc appendFromScript {
            nodeCmds::e1
    }
    $doc delete
    set nrOfNodeCmdsAfter [info commands domNode*]
    expr {$nrOfNodeCmdsBefore == $nrOfNodeCmdsAfter}
} {1}

test domDoc-22.4 {nodeCmd called outside of *FromScript context} {
    dom createNodeCmd elementNode e
    catch e
} 1

test domDoc-22.5 {nodeCmd use in child interp while in nodeCmd context} {
    set doc [dom createDocument this]
    set root [$doc documentElement]
    dom createNodeCmd elementNode thise
    dom createNodeCmd textNode t

    interp create childinterp
    load {} Tdom childinterp
    childinterp eval {
        dom createNodeCmd elementNode childe
        dom createNodeCmd textNode t
    }

    set result [catch {$root appendFromScript {
        thise {
            childinterp eval {
                childe {
                    t "other"
                }
            }
            t "some"
        }
    }}]
    $doc delete
    interp delete childinterp
    set result
} {1}

test domDoc-22.6 {nodeCmd use in child interp while in nodeCmd context} {
    set doc [dom createDocument this]
    set root [$doc documentElement]
    dom createNodeCmd elementNode thise
    dom createNodeCmd textNode t

    interp create childinterp
    load {} Tdom childinterp
    childinterp eval {
        dom createNodeCmd elementNode childe
        dom createNodeCmd textNode t
        set doc [dom createDocument child]
        set root [$doc documentElement]
    }

    $root appendFromScript {
        thise {
            childinterp eval {
                $root appendFromScript {
                    childe {
                        t "other"
                    }
                }
            }
            t "some"
        }
    }
    set result [$doc asXML -indent none]
    append result [childinterp eval {$doc asXML -indent none}]
    $doc delete
    interp delete childinterp
    set result
} {<this><thise>some</thise></this><child><childe>other</childe></child>}

test domDoc-23.1 {getElementsByTagNameNS} {
    dom createNodeCmd elementNode child

    set doc [dom createDocument root]
    $doc documentElement root
    $root appendFromScript {
        for {set x 0} {$x < 250} {incr x} {
            child [list xmlns ns$x] {}
        }
    }
    set xml [$doc asXML]
    $doc delete
    set doc [dom parse $xml]
    set result 1
    for {set x 0} {$x < 250} {incr x} {
        set nodes [$doc getElementsByTagNameNS ns$x *]
        if {[llength $nodes] != 1} {
            set result 0
        }
    }
    $doc delete
    set result
} {1}

test domDoc-24.1 {cdataSectionElements} {
    set doc [dom parse {<root>Some Text</root>}]
    set result [catch {$doc cdataSectionElements} errMsg]
    lappend result $errMsg
    $doc delete
    set result
} {1 {wrong # args: should be "<domDoc> cdataSectionElements ?URI:?localname ?boolean?"}}

test domDoc-24.2 {cdataSectionElements} {
    set doc [dom parse {<root>Some Text</root>}]
    set result [catch {$doc cdataSectionElements foo bar grill} errMsg]
    lappend result $errMsg
    $doc delete
    set result
} {1 {wrong # args: should be "<domDoc> cdataSectionElements ?URI:?localname ?boolean?"}}

test domDoc-24.3 {cdataSectionElements} {
    set doc [dom parse {<root>Some Text</root>}]
    set result [catch {$doc cdataSectionElements root foo} errMsg]
    lappend result $errMsg
    $doc delete
    set result
} {1 {expected boolean value but got "foo"}}
    
test domDoc-24.4 {cdataSectionElements} {
    set doc [dom parse {<root>Some Text</root>}]
    set result [$doc cdataSectionElements root]
    $doc delete
    set result
} {0}

test domDoc-24.5 {cdataSectionElements} {
    set doc [dom parse {<root>Some Text</root>}]
    set result [$doc cdataSectionElements root 0]
    lappend result [$doc cdataSectionElements root 1]
    lappend result [$doc cdataSectionElements root 0]
    $doc delete
    set result
} {0 1 0}

test domDoc-24.6 {cdataSectionElements} {
    set doc [dom parse {<root>Some Text</root>}]
    set result [$doc cdataSectionElements root 1]
    lappend result [$doc asXML -indent none]
    $doc delete
    set result
} {1 {<root><![CDATA[Some Text]]></root>}}

test domDoc-24.7 {cdataSectionElements} {
    set doc [dom parse {<root>&lt;foo></root>}]
    foreach element {foo root bar grill} {
        $doc cdataSectionElements $element 1
    }
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<root><![CDATA[<foo>]]></root>}

test domDoc-24.8 {cdataSectionElements} {
    set doc [dom parse {<root>text ]</root>}]
    $doc cdataSectionElements root 1
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<root><![CDATA[text ]]]></root>}

test domDoc-24.9 {cdataSectionElements} {
    set doc [dom parse {<root>text ]]</root>}]
    $doc cdataSectionElements root 1
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<root><![CDATA[text ]]]]></root>}

test domDoc-24.10 {cdataSectionElements} {
    set doc [dom parse {<root>text ]]&gt;</root>}]
    $doc cdataSectionElements root 1
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<root><![CDATA[text ]]]]><![CDATA[>]]></root>}

test domDoc-24.11 {cdataSectionElements} {
    set doc [dom parse {<root>text ]]&gt; text]]&gt;text</root>}]
    $doc cdataSectionElements root 1
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<root><![CDATA[text ]]]]><![CDATA[> text]]]]><![CDATA[>text]]></root>}

test domDoc-24.12 {cdataSectionElements} {
    set doc [dom parse {<root xmlns="http://foo.bar">text</root>}]
    $doc cdataSectionElements http://foo.bar:root 1
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<root xmlns="http://foo.bar"><![CDATA[text]]></root>}

test domDoc-24.13 {cdataSectionElements} {
    set doc [dom parse {<root>text</root>}]
    set result [$doc cdataSectionElements ""]
    $doc delete
    set result
} {0}

test domDoc-24.14 {cdataSectionElements} {
    set doc [dom parse {<root>text</root>}]
    set result [$doc cdataSectionElements *]
    $doc delete
    set result
} {}

test domDoc-24.15 {cdataSectionElements} {
    set doc [dom parse {<root>text</root>}]
    foreach elem {foo bar grill root http://www.foo.org:baz} {
        $doc cdataSectionElements $elem 1
    }
    foreach elem {foo grill} {
        $doc cdataSectionElements $elem 0
    }
    set result [lsort [$doc cdataSectionElements *]]
    $doc delete
    set result
} {bar http://www.foo.org:baz root}

test domDoc-24.16 {cdataSectionElements} {
    set doc [dom parse {<doc><child>some text</child></doc>}]
    $doc documentElement root
    set node [$root firstChild]
    $doc cdataSectionElements child 1
    set result [$node asXML -indent none]
    $doc delete
    set result
} {<child><![CDATA[some text]]></child>}

test domDoc-24.17 {cdataSectionElements} {
    set doc [dom parse {<doc><child>some text <b>more text</b> text again</child></doc>}]
    $doc cdataSectionElements child 1
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc><child><![CDATA[some text ]]><b>more text</b><![CDATA[ text again]]></child></doc>}


test domDoc-25.1 {selectNodesNamespaces} {
    set doc [dom createDocument foo]
    set result [$doc selectNodesNamespaces]
    $doc delete
    set result
} {}

test domDoc-25.2 {selectNodesNamespaces} {
    set doc [dom createDocument foo]
    set result [list [$doc selectNodesNamespaces] \
                    [$doc selectNodesNamespaces {}] \
                    [$doc selectNodesNamespaces]]
    $doc delete
    set result
} {{} {} {}}

test domDoc-25.3 {selectNodesNamespaces} {
    set doc [dom createDocument foo]
    set result [list [$doc selectNodesNamespaces] \
                    [$doc selectNodesNamespaces {prefix http://foo.org/uri}] \
                    [$doc selectNodesNamespaces] \
                    [$doc selectNodesNamespaces {}]]
    $doc delete
    set result
} {{} {prefix http://foo.org/uri} {prefix http://foo.org/uri} {}}

test domDoc-25.4 {selectNodesNamespaces} {
    set doc [dom createDocument foo]
    set result [catch {$doc selectNodesNamespaces wrong} errMsg]
    lappend result $errMsg
    $doc delete
    set result
} {1 {The optional argument to selectNodesNamespaces must be a 'prefix namespace' pairs list}}

test domDoc-25.5 {selectNodesNamespaces} {
    set doc [dom parse {<root xmlns="rootdefaultNS">
        <elem1 xmlns="elem1NS"><elem11/></elem1>
        <elem2 xmlns="elem2NS"/>
        </root>}]
    $doc selectNodesNamespaces {default1 rootdefaultNS}
    set node [$doc selectNodes default1:root]
    set result [list [$node prefix] [$node localName]]
    $doc delete
    set result
} {{} root}

test domDoc-25.6 {selectNodesNamespaces} {
    set doc [dom parse {<root xmlns="rootdefaultNS">
        <elem1 xmlns="elem1NS"><elem11/></elem1>
        <elem2 xmlns="elem2NS"/>
        </root>}]
    $doc selectNodesNamespaces {default2 elem1NS default1 rootdefaultNS}
    set node [$doc selectNodes default1:root/default2:elem1]
    set result [list [$node prefix] [$node localName]]
    set node [$doc selectNodes default1:root/default2:elem1/default2:elem11]
    lappend result [$node nodeName] [$node namespaceURI]
    $doc delete
    set result
} {{} elem1 elem11 elem1NS}

test domDoc-25.7 {selectNodesNamespaces} {
    set doc [dom parse {<root xmlns="rootdefaultNS">
        <elem1 xmlns="elem1NS"><elem11 xmlns=""/></elem1>
        <elem2 xmlns="elem2NS"/>
        </root>}]
    $doc selectNodesNamespaces {default2 elem1NS default1 rootdefaultNS}
    set node [$doc selectNodes default1:root/default2:elem1]
    set result [list [$node prefix] [$node localName]]
    set node [$doc selectNodes default1:root/default2:elem1/elem11]
    lappend result [$node nodeName] [$node namespaceURI]
    $doc delete
    set result
} {{} elem1 elem11 {}}

test domDoc-25.7.1 {selectNodesNamespaces} {
    set doc [dom parse {<root xmlns="rootdefaultNS">
        <elem1 xmlns="elem1NS"/>
        <elem2 xmlns="elem2NS"/>
        </root>}]
    $doc documentElement root
    $root firstChild elem1
    $doc createElement elem11 elem11
    $elem1 appendChild $elem11
    $doc selectNodesNamespaces {default2 elem1NS default1 rootdefaultNS}
    set node [$doc selectNodes default1:root/default2:elem1]
    set result [list [$node prefix] [$node localName]]
    set node [$doc selectNodes default1:root/default2:elem1/elem11]
    lappend result [$node nodeName] [$node namespaceURI]
    $doc delete
    set result
} {{} elem1 elem11 {}}

test domDoc-25.8 {selectNodesNamespaces} {
    set doc [dom parse {<root xmlns="rootdefaultNS">
        <elem1 xmlns="elem1NS"><elem11 xmlns=""/></elem1>
        <elem2 xmlns="elem2NS"/>
        </root>}]
    $doc selectNodesNamespaces {default2 elem1NS default1 rootdefaultNS}
    set result [catch {set node [$doc selectNodes \
                                     -namespaces {
                                         dflt1 elem1NS 
                                         dflt2 rootdefaultNS
                                     } \
                                     default1:root/dflt1:elem1/elem11]} errMsg]
    lappend result $errMsg
    $doc delete
    set result
} {1 {Prefix doesn't resolve}}

test domDoc-25.9 {selectNodesNamespaces} {
    set doc [dom parse {<root xmlns="rootdefaultNS">
        <elem1 xmlns="elem1NS"><elem11 xmlns=""/></elem1>
        <elem2 xmlns="elem2NS"/>
        </root>}]
    $doc selectNodesNamespaces {default2 elem1NS default1 rootdefaultNS}
    set node [$doc selectNodes default1:root/default2:elem1]
    set result [list [$node prefix] [$node localName]]
    set node [$doc selectNodes \
                  -namespaces {dflt1 elem1NS dflt2 rootdefaultNS} \
                  dflt2:root/dflt1:elem1/elem11]
    lappend result [$node nodeName] [$node namespaceURI]
    $doc delete
    set result
} {{} elem1 elem11 {}}


test domDoc-26.1 {Fragment list} {
    set doc [dom parse {<!---comment on top level-->
        <root>text1<child>text2</child>text3</root>}]
    $doc removeChild [$doc firstChild]
    $doc documentElement root
    for {set i 1} {$i < 4} {incr i} {
        set removedNode$i [$root removeChild [$root firstChild]]
    }
    $removedNode2 delete
    $root appendChild $removedNode3
    $root appendChild $removedNode1
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<root>text3text1</root>}

test domDoc-27.1 {deleteXPathCache} {
    set doc [dom createDocument doc]
    set result [list]
    lappend result [$doc deleteXPathCache foo/bar]
    $doc selectNodes -cache 1 2+2
    lappend result [$doc deleteXPathCache foo/bar]
    lappend result [$doc deleteXPathCache 2+2]
    lappend result [$doc deleteXPathCache]
    $doc selectNodes -cache 1 2+2
    $doc delete
    set result
} {{} {} {} {}}

test domDoc-28.1 {createElementNS} {
    set doc [dom createDocument doc]
    set newElem [$doc createElementNS uri ns:e]
    $doc documentElement root
    $root appendChild $newElem
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc><ns:e xmlns:ns="uri"/></doc>}

test domDoc-28.2 {createElementNS} {
    set doc [dom createDocument doc]
    set newElem [$doc createElementNS uri ns:e]
    $newElem setAttributeNS uri ns:att value
    $doc documentElement root
    $root appendChild $newElem
    set result [$doc selectNodes -namespaces {ns uri} string(/doc/ns:e/@ns:att)]
    $doc delete
    set result
} {value}

test domDoc-28.3 {createElementNS} {
    set doc [dom createDocument doc]
    catch {$doc createElementNS "" e} errMsg
    $doc delete
    set errMsg
} {Missing URI in Namespace declaration}

test domDoc-29.1 {asCanonicalXML} {
    set doc [dom parse -keepEmpties {<?xml version="1.0"?>

<?xml-stylesheet   href="doc.xsl"
   type="text/xsl"   ?>

<!DOCTYPE doc SYSTEM "doc.dtd">

<doc>Hello, world!<!-- Comment 1 --></doc>

<?pi-without-data     ?>

<!-- Comment 2 -->

<!-- Comment 3 -->}]
    set result [$doc asCanonicalXML]
    $doc delete
    set result
} {<?xml-stylesheet href="doc.xsl"
   type="text/xsl"   ?>
<doc>Hello, world!</doc>
<?pi-without-data?>}

test domDoc-29.2 {asCanonicalXML} {
    set doc [dom parse -keepEmpties {<?xml version="1.0"?>

<?xml-stylesheet   href="doc.xsl"
   type="text/xsl"   ?>

<!DOCTYPE doc SYSTEM "doc.dtd">

<doc>Hello, world!<!-- Comment 1 --></doc>

<?pi-without-data     ?>

<!-- Comment 2 -->

<!-- Comment 3 -->}]
    set result [$doc asCanonicalXML -comments 1]
    $doc delete
    set result
} {<?xml-stylesheet href="doc.xsl"
   type="text/xsl"   ?>
<doc>Hello, world!<!-- Comment 1 --></doc>
<?pi-without-data?>
<!-- Comment 2 -->
<!-- Comment 3 -->}

test domDoc-29.3 {asCanonicalXML} {
    set doc [dom parse -keepEmpties {<doc>
   <clean>   </clean>
   <dirty>   A   B   </dirty>
   <mixed>
      A
      <clean>   </clean>
      B
      <dirty>   A   B   </dirty>
      C
   </mixed>
</doc>}]
    set result [$doc asCanonicalXML]
    $doc delete
    set result
} {<doc>
   <clean>   </clean>
   <dirty>   A   B   </dirty>
   <mixed>
      A
      <clean>   </clean>
      B
      <dirty>   A   B   </dirty>
      C
   </mixed>
</doc>}

test domDoc-29.5 {asCanonicalXML} {
    set doc [dom parse -keepEmpties {<!DOCTYPE doc [<!ATTLIST e9 attr CDATA "default">]>
<doc>
   <e1   />
   <e2   ></e2>
   <e3   name = "elem3"   id="elem3"   />
   <e4   name="elem4"   id="elem4"   ></e4>
   <e5 a:attr="out" b:attr="sorted" attr2="all" attr="I'm"
      xmlns:b="http://www.ietf.org"
      xmlns:a="http://www.w3.org"
      xmlns="http://example.org"/>
   <e6 xmlns="" xmlns:a="http://www.w3.org">
      <e7 xmlns="http://www.ietf.org">
         <e8 xmlns="" xmlns:a="http://www.w3.org">
            <e9 xmlns="" xmlns:a="http://www.ietf.org"/>
         </e8>
      </e7>
   </e6>
</doc>}]
    set result [$doc asCanonicalXML]
    $doc delete
    set result
} {<doc>
   <e1></e1>
   <e2></e2>
   <e3 id="elem3" name="elem3"></e3>
   <e4 id="elem4" name="elem4"></e4>
   <e5 xmlns="http://example.org" xmlns:a="http://www.w3.org" xmlns:b="http://www.ietf.org" attr="I'm" attr2="all" b:attr="sorted" a:attr="out"></e5>
   <e6 xmlns:a="http://www.w3.org">
      <e7 xmlns="http://www.ietf.org">
         <e8 xmlns="">
            <e9 xmlns:a="http://www.ietf.org" attr="default"></e9>
         </e8>
      </e7>
   </e6>
</doc>}

test domDoc-29.6 {asCanonicalXML} {
    set doc [dom parse -keepEmpties {<!DOCTYPE doc [
<!ATTLIST normId id ID #IMPLIED>
<!ATTLIST normNames attr NMTOKENS #IMPLIED>
]>
<doc>
   <text>First line&#x0d;&#10;Second line</text>
   <value>&#x32;</value>
   <compute><![CDATA[value>"0" && value<"10" ?"valid":"error"]]></compute>
   <compute expr='value>"0" &amp;&amp; value&lt;"10" ?"valid":"error"'>valid</compute>
   <norm attr=' &apos;   &#x20;&#13;&#xa;&#9;   &apos; '/>
   <normNames attr='   A   &#x20;&#13;&#xa;&#9;   B   '/>
   <normId id=' &apos;   &#x20;&#13;&#xa;&#9;   &apos; '/>
</doc>}]
    set result [$doc asCanonicalXML]
    $doc delete
    set result
} {<doc>
   <text>First line&#xD;
Second line</text>
   <value>2</value>
   <compute>value&gt;"0" &amp;&amp; value&lt;"10" ?"valid":"error"</compute>
   <compute expr="value>&quot;0&quot; &amp;&amp; value&lt;&quot;10&quot; ?&quot;valid&quot;:&quot;error&quot;">valid</compute>
   <norm attr=" '    &#xD;&#xA;&#x9;   ' "></norm>
   <normNames attr="A &#xD;&#xA;&#x9; B"></normNames>
   <normId id="' &#xD;&#xA;&#x9; '"></normId>
</doc>}

proc 29.7 {base system public} {
    switch $system {
        "world.txt" {
            return [list "string" "" "world"]
        }
        "earth.gif" {
            return [list "string" "" ""]
        }
        default {
            error "unexpected system URL '$system'"
        }
    }
}

test domDoc-29.7 {asCanonicalXML} {
    set doc [dom parse -externalentitycommand 29.7 -keepEmpties {<!DOCTYPE doc [
<!ATTLIST doc attrExtEnt ENTITY #IMPLIED>
<!ENTITY ent1 "Hello">
<!ENTITY ent2 SYSTEM "world.txt">
<!ENTITY entExt SYSTEM "earth.gif" NDATA gif>
<!NOTATION gif SYSTEM "viewgif.exe">
]>
<doc attrExtEnt="entExt">
   &ent1;, &ent2;!
</doc>

<!-- Let world.txt contain "world" (excluding the quotes) -->}]
    set result [$doc asCanonicalXML]
    $doc delete
    set result
} {<doc attrExtEnt="entExt">
   Hello, world!
</doc>}

test domDoc-29.8 {asCanonicalXML} {
    set doc [dom parse -keepEmpties {<?xml version="1.0" encoding="ISO-8859-1"?>
<doc>&#169;</doc>}]
    set result [$doc asCanonicalXML]
    $doc delete
    set result
} "<doc>\u00A9</doc>"

test domDoc-30.1 {cmd argument parsing} {
    set result [catch {domDoc} errMsg]
    lappend result $errMsg
    catch {domDoc foo} errMsg
    lappend result $errMsg
} {1 {wrong # args: should be "domDoc doctoken subcommand ?arg ...?"} {wrong # args: should be "domDoc doctoken subcommand ?arg ...?"}}

test domDoc-30.2 {cmd argument parsing} {
    set storedMode [dom setObjectCommands]
    dom setObjectCommands token
    set doc [dom parse {<doc><e/></doc>}]
    catch {domDoc $doc} result
    domDoc $doc delete
    dom setObjectCommands $storedMode
    set result
} {wrong # args: should be "domDoc doctoken subcommand ?arg ...?"}

test domDoc-30.3 {cmd argument parsing} -body {
    set doc [dom parse {<doc><e/></doc>}]
    catch {$doc} result
    $doc delete
    set result
} -match regexp -result {wrong # args: should be "domDoc[^ ]+ subcommand \?arg ...\?"}

test domDoc-30.4 {cmd argument parsing} -body {
    set storedMode [dom setObjectCommands]
    dom setObjectCommands token
    set doc [dom parse {<doc><e/></doc>}]
    catch {domDoc $doc invalid-method} result
    domDoc $doc delete
    dom setObjectCommands $storedMode
    set result
} -match glob -result {bad method "invalid-method": must be *}

test domDoc-30.5 {cmd argument parsing} -body {
    set doc [dom parse {<doc><e/></doc>}]
    catch {$doc invalid-method} result
    $doc delete
    set result
} -match glob -result {bad method "invalid-method": must be *}

# test domDoc-29.9 {asCanonicalXML} {
#     set doc [dom parse -keepEmpties {}]
#     set result [$doc asCanonicalXML]
#     $doc delete
#     set result
# } {}

# cleanup
::tcltest::cleanupTests
return
