<html> <head> <link rel="stylesheet" href="../../js/resources/js-test-style.css"> <script src="../../js/resources/js-test-pre.js"></script> <script src="../xpath-test-pre.js"></script> </head> <body> <div id="console"></div> <script> var doc = (new DOMParser).parseFromString( '<!DOCTYPE doc [<!ATTLIST item identifier ID #IMPLIED>]>' + '<doc>' + '<item id="1" identifier="a" />' + '<item id="2" identifier="b" />' + '<item id="3" identifier="c" />' + '<item id="4" identifier="d" />' + '<item id="5" identifier="e" />' + '<reference>a</reference>' + '<reference>c</reference>' + '<reference>e</reference>' + '<namespace xmlns="http://www.example.com/a" xmlns:b="http://www.example.com/b">' + '<item id="6" />' + '<b:item id="7" b:value="42" />' + '</namespace>' + '</doc>', 'application/xml'); var ROOT = doc.documentElement; var ITEM1 = ROOT.firstChild; var ITEM2 = ITEM1.nextSibling; var ITEM3 = ITEM2.nextSibling; var ITEM4 = ITEM3.nextSibling; var ITEM5 = ITEM4.nextSibling; var REFA = ITEM5.nextSibling; var REFC = REFA.nextSibling; var REFE = REFC.nextSibling; var NAMESPACE = REFE.nextSibling; var ITEM6 = NAMESPACE.firstChild; var ITEM7 = ITEM6.nextSibling; test(doc, ROOT, '//item[@id=last()]', [ITEM5]); test(doc, ROOT, '//item[position()=3]', [ITEM3]); test(doc, ROOT, 'count(//item)', 5); test(doc, ROOT, 'id("c")', [ITEM3]); test(doc, ROOT, 'id(//reference)', [ITEM1, ITEM3, ITEM5]); // The below test is wrong, it has an invalid expression. //test(doc, ROOT, '//reference/id("a")', [ITEM1]); // Several tests below originally used predicates with an abbreviated step, which is formally invalid, see <https://bugs.webkit.org/show_bug.cgi?id=12632>. test(doc, ROOT, 'local-name(//self::node()[@id=7])', 'item'); test(doc, ROOT, 'number(//self::node()[@id=7]/attribute::*[local-name()="value"])', 42); test(doc, ROOT, 'local-name(/absent)', ''); test(doc, ROOT, 'namespace-uri(//self::node()[@id>5])', 'http://www.example.com/a'); test(doc, ROOT, '//self::node()[@id and namespace-uri()="http://www.example.com/b"]', [ITEM7]); test(doc, ROOT, 'namespace-uri(/absent)', ''); test(doc, ROOT, 'name(//self::node()[@id=7])', 'b:item'); test(doc, ROOT, '//self::node()[name()="b:item"]', [ITEM7]); test(doc, ROOT, 'name(/absent)', ''); doc = (new DOMParser).parseFromString( '<doc>' + '<para id="1">One</para>' + '<para id="2">Two</para>' + '<para id="3">Three</para>' + '<para id="4">' + 'Four' + '</para>' + '</doc>', 'application/xml'); var ROOT = doc.documentElement; var PARA1 = ROOT.firstChild; var PARA2 = PARA1.nextSibling; var PARA3 = PARA2.nextSibling; var PARA4 = PARA3.nextSibling; test(doc, doc, 'string(//para)', 'One'); test(doc, doc, 'string(//inconceivable)', ''); test(doc, doc, 'string(0 div 0)', 'NaN'); test(doc, doc, 'string(1 div 0)', 'Infinity'); test(doc, doc, 'string(-1 div 0)', '-Infinity'); test(doc, doc, 'string(2.5 * 2)', '5'); test(doc, doc, 'string(1 div -2)', '-0.5'); test(doc, doc, 'string(1 = 2)', 'false'); test(doc, doc, 'string("string")', 'string'); test(doc, doc, '//para[string()="Two"]', [PARA2]); test(doc, doc, 'concat(//para, ":", //para[2])', 'One:Two'); test(doc, doc, 'starts-with("foo-bar", "foo")', true); test(doc, doc, 'starts-with("foo-bar", "bar")', false); test(doc, doc, 'contains("foo-bar", "o-b")', true); test(doc, doc, 'contains("foo-bar", "b-o")', false); test(doc, doc, 'substring-before("foo::bar", "::")', 'foo'); test(doc, doc, 'substring-before("foo::bar", "--")', ''); test(doc, doc, 'substring-after("foo::bar", "::")', 'bar'); test(doc, doc, 'substring-after("foo::bar", "--")', ''); test(doc, doc, 'substring("12345", 2)', '2345'); test(doc, doc, 'substring("12345", 2, 3)', '234'); test(doc, doc, 'substring("12345", 1.5, 2.6)', '234'); test(doc, doc, 'substring("12345", 0, 3)', '12'); test(doc, doc, 'substring("12345", 0 div 0, 3)', ''); test(doc, doc, 'substring("12345", 1, 0 div 0)', ''); test(doc, doc, 'substring("12345", -42, 1 div 0)', '12345'); test(doc, doc, 'substring("12345", -1 div 0, 1 div 0)', ''); test(doc, doc, 'substring("12345", 6, 1)', ''); test(doc, doc, 'substring("12345", 1, 0)', ''); test(doc, doc, 'string-length("12345")', 5); test(doc, doc, '//para[string-length()=5]', [PARA3]); test(doc, doc, 'normalize-space(" one two ")', 'one two'); test(doc, doc, '//para[normalize-space() = "Four"]', [PARA4]); test(doc, doc, 'translate("abcdef", "abcde", "xyz")', 'xyzf'); doc = (new DOMParser).parseFromString( '<doc id="0">' + '<para id="1" />' + '<para id="2" xml:lang="en">' + '<item id="3" />' + 'English' + '<section id="4" xml:lang="jp">' + '<item id="5" />' + 'Nihongo' + '</section>' + '</para>' + '<para id="6" xml:lang="EN">' + 'ENGLISH' + '</para>' + '<para id="7" xml:lang="en-us">' + 'US English' + '</para>' + '<para id="8" xml:lang="EN-UK">' + 'UK English' + '</para>' + '</doc>', 'application/xml'); var ROOT = doc.documentElement; var PARA1 = ROOT.firstChild; var PARA2 = PARA1.nextSibling; var ITEM3 = PARA2.firstChild; var SECTION4 = ITEM3.nextSibling.nextSibling; var ITEM5 = SECTION4.firstChild; var PARA6 = PARA2.nextSibling; var PARA7 = PARA6.nextSibling; var PARA8 = PARA7.nextSibling; test(doc, doc, 'boolean(1)', true); test(doc, doc, 'boolean(0)', false); test(doc, doc, 'boolean(0 div 0)', false); test(doc, doc, 'boolean(cod)', false); test(doc, doc, 'boolean(doc)', true); test(doc, doc, 'boolean("")', false); test(doc, doc, 'boolean("foo")', true); test(doc, doc, 'not(1 = 1)', false); test(doc, doc, 'true()', true); test(doc, doc, 'false()', false); test(doc, doc, '//*[lang("en")]', [PARA2, ITEM3, PARA6, PARA7, PARA8]); test(doc, doc, '//*[lang("EN-US")]', [PARA7]); test(doc, doc, 'normalize-space((//text()[lang("jp")])[normalize-space()])', 'Nihongo'); doc = (new DOMParser).parseFromString( '<doc>' + '<item>1</item>' + '<item>2</item>' + '<item>3</item>' + '</doc>', 'application/xml'); test(doc, doc, 'string(number("-1e5"))', 'NaN'); // This test originally checked for successful parsing, but -1e5 is not a valid XPath number. test(doc, doc, 'number(true())', 1); test(doc, doc, 'number(false())', 0); test(doc, doc, 'number(//item)', 1); test(doc, doc, 'string(//item[number()=4 div 2])', '2'); test(doc, doc, 'sum(//item)', 6); test(doc, doc, 'floor(1.99)', 1); test(doc, doc, 'floor(-1.99)', -2); test(doc, doc, 'ceiling(1.99)', 2); test(doc, doc, 'ceiling(-1.99)', -1); test(doc, doc, 'round(1.5)', 2); test(doc, doc, 'round(-1.5)', -1); test(doc, doc, 'string(round(0 div 0))', 'NaN'); test(doc, doc, 'round(1 div 0)', 1 / 0); test(doc, doc, 'round(-1 div 0)', -1 / 0); // The below tests are added for WebKit to complement the -1e5 test above. test(doc, doc, 'number(".1")', 0.1); test(doc, doc, 'number("1.")', 1); test(doc, doc, 'string(number(".1."))', 'NaN'); test(doc, doc, 'string(number("..1"))', 'NaN'); test(doc, doc, 'string(number("1.."))', 'NaN'); test(doc, doc, 'string(number(".-1"))', 'NaN'); var successfullyParsed = true; </script> <script src="../../js/resources/js-test-post.js"></script> </body> </html>