From 1ed130e2e1cc8ab115ec46784b1684dfc02d0095 Mon Sep 17 00:00:00 2001 From: sergei Date: Mon, 14 Jun 2010 17:21:35 +0000 Subject: [PATCH] * Fixed XPath functions name() and local-name(), which should behave different from DOM properties of the same names. name() is empty for text, comment and document nodes. local-name() is the same as name() for non-prefixed attributes and processing instructions. + Another dozen of tests. git-svn-id: trunk@15438 - --- packages/fcl-xml/src/xpath.pp | 28 +++++++++++++----- packages/fcl-xml/tests/xpathts.pp | 48 +++++++++++++++++++++++++++---- 2 files changed, 64 insertions(+), 12 deletions(-) diff --git a/packages/fcl-xml/src/xpath.pp b/packages/fcl-xml/src/xpath.pp index 7c088343e0..31da5c3d5d 100644 --- a/packages/fcl-xml/src/xpath.pp +++ b/packages/fcl-xml/src/xpath.pp @@ -2534,10 +2534,18 @@ begin if NodeSet.Count > 0 then n := TDOMNode(NodeSet[0]); end; + s := ''; if Assigned(n) then - s := n.localName - else - s := ''; + begin + case n.NodeType of + ELEMENT_NODE,ATTRIBUTE_NODE: + with TDOMNode_NS(n) do + s := Copy(NSI.QName^.Key, NSI.PrefixLen+1, MaxInt); + PROCESSING_INSTRUCTION_NODE: + s := TDOMProcessingInstruction(n).Target; + // TODO: NAMESPACE_NODE: must return prefix part + end; + end; Result := TXPathStringVariable.Create(s); end; @@ -2582,11 +2590,17 @@ begin if NodeSet.Count > 0 then n := TDOMNode(NodeSet[0]); end; - // TODO: probably this isn't correct. XPath name() isn't the same as DOM nodeName. + s := ''; if Assigned(n) then - s := n.nodeName - else - s := ''; + begin + case n.NodeType of + ELEMENT_NODE,ATTRIBUTE_NODE: + s := TDOMNode_NS(n).NSI.QName^.Key; + PROCESSING_INSTRUCTION_NODE: + s := TDOMProcessingInstruction(n).Target; + // TODO: NAMESPACE_NODE: must return prefix part + end; + end; Result := TXPathStringVariable.Create(s); end; diff --git a/packages/fcl-xml/tests/xpathts.pp b/packages/fcl-xml/tests/xpathts.pp index 50bfbd6d4f..1dbd986d12 100644 --- a/packages/fcl-xml/tests/xpathts.pp +++ b/packages/fcl-xml/tests/xpathts.pp @@ -552,7 +552,16 @@ const ''#10+ ''; - StringTests: array[0..74] of TTestRec = ( // numbers refer to xalan/string/stringXX + ns11=''+ + ' Hello'+ + ' '+ + ' '+ + ' '+ + ''; + + pidata=''; + + StringTests: array[0..87] of TTestRec = ( // numbers refer to xalan/string/stringXX (expr: 'string(0)'; rt: rtString; s: '0'), (expr: 'string(5)'; rt: rtString; s: '5'), // #38/39 (expr: 'string(0.5)'; rt: rtString; s: '0.5'), @@ -633,6 +642,23 @@ const (expr: 'translate("--aaa--","abc-","ABC")'; rt: rtString; s: 'AAA'), (expr: 'translate("ddaaadddd","abcd","ABCxy")'; rt: rtString; s: 'xxAAAxxxx'), // #96 + (data: node08; expr: 'name(a/@attr1)'; rt: rtString; s: 'attr1'), // namespace08 modified + (data: node08; expr: 'namespace-uri(a/@attr1)'; rt: rtString; s: ''), + (data: node08; expr: 'local-name(a/@attr1)'; rt: rtString; s: 'attr1'), + + (data: pidata; expr: 'name(/processing-instruction())'; rt: rtString; s: 'a-pi'), // namespace29 modified + (data: pidata; expr: 'name(/processing-instruction("b-pi"))'; rt: rtString; s: 'b-pi'), + (data: pidata; expr: 'local-name(/processing-instruction())'; rt: rtString; s: 'a-pi'), + (data: pidata; expr: 'namespace-uri(/processing-instruction())'; rt: rtString; s: ''), + + (data: node08; expr: 'name(//comment())'; rt: rtString; s: ''), // namespace30 modified + (data: node08; expr: 'local-name(//comment())'; rt: rtString; s: ''), + (data: node08; expr: 'namespace-uri(//comment())'; rt: rtString; s: ''), + + (data: node08; expr: 'name(//text())'; rt: rtString; s: ''), // namespace31 modified + (data: node08; expr: 'local-name(//text())'; rt: rtString; s: ''), + (data: node08; expr: 'namespace-uri(//text())'; rt: rtString; s: ''), + // tests for number->string conversions at boundary conditions (expr: 'string(123456789012345678)'; rt: rtString; s: '123456789012345680'), // #132.1 (expr: 'string(-123456789012345678)'; rt: rtString; s: '-123456789012345680'), // #132.2 @@ -649,7 +675,7 @@ const res1 = ''; - nameTests: array[0..9] of TTestRec3 = ( + nameTests: array[0..16] of TTestRec3 = ( (data: str30; re: res1; expr: 'namespace-uri(baz1:a/@baz2:attrib1)'; rt: rtString; s: ''), // #30 (data: str30; re: res1; expr: 'namespace-uri(baz2:b/@baz1:attrib2)'; rt: rtString; s: 'http://xsl.lotus.com/ns1'), // #31 (data: str30; re: res1; expr: 'name(*)'; rt: rtString; s: 'ns1:a'), // #32 @@ -660,7 +686,16 @@ const (data: str30; re: res1; expr: 'local-name(baz2:b)'; rt: rtString; s: 'b'), // namespace07 (data: str30; re: res1; expr: 'local-name(baz2:b/@baz1:attrib2)'; rt: rtString; s: 'attrib2'), // namespace09 - (data: str30; re: res1; expr: 'local-name()'; rt: rtString; s: 'doc') // namespace26 + (data: str30; re: res1; expr: 'local-name()'; rt: rtString; s: 'doc'), // namespace26 + (data: str30; re: res1; expr: 'namespace-uri()'; rt: rtString; s: 'http://xsl.lotus.com/ns2'), // namespace27 + + (data: ns11; re: res1; expr: 'namespace-uri(baz1:a-two)'; rt: rtString; s: 'http://xsl.lotus.com/ns1'), // namespace11 + (data: ns11; re: res1; expr: 'namespace-uri(baz1:a-two/@attrib1)'; rt: rtString; s: ''), + (data: ns11; re: res1; expr: 'namespace-uri(baz2:b-three)'; rt: rtString; s: 'http://xsl.lotus.com/ns2'), + (data: ns11; re: res1; expr: 'namespace-uri(baz2:b-three/@baz1:attrib2)'; rt: rtString; s: 'http://xsl.lotus.com/ns1'), +{*} (data: ns11; re: res1; expr: 'namespace-uri(baz2:b-three/c-four)'; rt: rtString; s: ''), + (data: ns11; re: res1; expr: 'namespace-uri(bogus)'; rt: rtString; s: '') + ); ax114=''+ @@ -700,7 +735,7 @@ const ''+ ''; - AxesTests: array[0..13] of TTestRec = ( + AxesTests: array[0..15] of TTestRec = ( (data: ax117; expr: 'count(//@*)'; rt: rtNumber; n: 16), (data: ax117; expr: 'count(//@title)'; rt: rtNumber; n: 12), (data: ax117; expr: 'count(//section//@*)'; rt: rtNumber; n: 14), @@ -716,8 +751,11 @@ const (data: ax114; expr: '//baz/preceding::foo[1]/@att1'; rt: rtNodeStr; s: 'a'), // (data: ax114; expr: '//baz/(preceding::foo)[1]/@att1'; rt: rtNodeStr; s: 'c'), // won't parse - (data: ax115; expr: '//baz/preceding-sibling::foo[1]/@att1'; rt: rtNodeStr; s: 'a') + (data: ax115; expr: '//baz/preceding-sibling::foo[1]/@att1'; rt: rtNodeStr; s: 'a'), // (data: ax115; expr: '//baz/(preceding-sibling::foo)[1]/@att1'; rt: rtNodeStr; s: 'c') // won't parse + + (data: simple; expr: 'local-name(namespace::*[1])'; rt: rtString; s: 'xml'), // namespace28a + (data: simple; expr: 'name(namespace::*[1])'; rt: rtString; s: 'xml') // namespace28b ); {$warnings on}