From: <bi...@us...> - 2012-07-18 23:36:30
|
Revision: 8105 http://oorexx.svn.sourceforge.net/oorexx/?rev=8105&view=rev Author: bigrixx Date: 2012-07-18 23:36:24 +0000 (Wed, 18 Jul 2012) Log Message: ----------- More xpath work Modified Paths: -------------- incubator/orxutils/xml/xmldom.cls Modified: incubator/orxutils/xml/xmldom.cls =================================================================== --- incubator/orxutils/xml/xmldom.cls 2012-07-18 23:18:42 UTC (rev 8104) +++ incubator/orxutils/xml/xmldom.cls 2012-07-18 23:36:24 UTC (rev 8105) @@ -224,7 +224,6 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ - -- DOM Node interface class ::class "Node" public mixinclass Object -- various type definitions @@ -686,7 +685,6 @@ ::constant XPATH_NAMESPACE_NODE 13 ::method ownerElement abstract - /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* Class: NodeIterator */ @@ -2425,22 +2423,6 @@ ::method changes return self~ownerdocument~changes --- select a set of nodes using an xpath expression -::method selectNodeSet - use strict arg path - - -- any errors are just treated as selection failures and return an - -- empty node set - signal on syntax - - -- parse the expression and execute using this node as the starting context - parser = .XpathParser~new(self~document, path) - expr = parse~parse - return expr~evaluate(self, .nil) - - syntax: - -- just return an empty node set - -- methods for the DOMEventTracker interface -- add a listener to this node @@ -4216,7 +4198,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -/* Class: Text -- a DOM comment node */ +/* Class: Comment -- a DOM comment node */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ @@ -4940,6 +4922,7 @@ /* Class: DOMEvent */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ + ::class "DOMEvent" public -- phase definitions ::constant NONE 0 @@ -6702,6 +6685,7 @@ /* Class: DocumentImpl */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ + ::class "DocumentImpl" subclass ParentNode public inherit Document DocumentTraversal DocumentEvent DocumentRange ::method init expose iterators ranges eventListeners userData identifiers doctype - @@ -8238,7 +8222,6 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ - ::class "XPath" ::constant INVALID_OPERATOR_ERROR "Invalid XPath operator found" ::constant INVALID_EXPRESSION_ERROR "Invalid XPath expression." @@ -8258,6 +8241,12 @@ use strict arg reason raise syntax 93.900 array(reason) +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: TokenQueue */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + -- a queue of tokens ::class "TokenQueue" ::method init @@ -8305,6 +8294,11 @@ expose queue queue~pop +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: XPathToken */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ -- a generic token value. Most of the work here is done via class methods. -- the token itself is very general and very simple @@ -8539,6 +8533,12 @@ -- special test for operator tokens -- default is always false ::attribute isOperator GET +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: XPathOperatorToken */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + -- special subclass for the operators ::class "XPathOperatorToken" subclass XPathToken ::method init @@ -8553,6 +8553,12 @@ -- operator precedence value ::attribute precedence GET +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: XPathScanner */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + -- a class to scan an xpath expression and break it up into its tokens. ::class "XPathScanner" ::method init class @@ -9004,8 +9010,14 @@ tokens~addToken(.XPathToken~numbertoken(number)) return currentOffset; +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: XPathNodeTest */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + -- test for a node match -::class "NodeTest" +::class "XPathNodeTest" ::method init expose nameTest typeTest use strict arg nameTest = .nil, typeTest = (.Node~ANY_NODE) @@ -9018,6 +9030,11 @@ if nameTest \= .nil then return nodeset~getNamedItems(nameTest) else nodeset~getTypedItems(typeTest) +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: XPathConversions */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ ::class "XPathConversions" mixinclass object -- Apply the xpath rules for boolean true/false to an expression result @@ -9111,6 +9128,11 @@ end -- all other node types don't add anything else return +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: XPathExpr */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ -- base class for an xpath expression term ::class "XpathExpr" inherit XPathConversions @@ -9163,12 +9185,17 @@ -- some inspection return self~convertBoolean(result) +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: XPathStep */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ -- an axis evaluation step in an expression ::class "XpathStep" subclass xpathexpr ::method init expose axis nodeTest predicates - use strict arg axis, nodeTest = (.NodeTest~new(.Node~ANY_NODE)), predicates = (.array~new) + use strict arg axis, nodeTest = (.XPathNodeTest~new(.Node~ANY_NODE)), predicates = (.array~new) ::method evaluate expose axis nodeTest @@ -9192,6 +9219,12 @@ return nodeSet +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: XPathDyadicOperator */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + -- a dyadic expression term ::class "XPathDyadicOperator" subclass XPathExpr ::method init @@ -9560,6 +9593,12 @@ return union +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: XPathUnaryOperator */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + -- a unary operator expression term ::class "XPathUnaryOperator" subclass XPathExpr ::method init @@ -9575,6 +9614,12 @@ -- value return - self~evaluateNumber(term) +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: XPathLiteral */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + -- a literal value as an expression term ::class "XPathLiteral" subclass XPathExpr ::method init @@ -9588,6 +9633,12 @@ -- just return this without evaluation return value +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: XPathFunctionCall */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + ::class "XPathFunctionCall" subclass XPathExpr ::method init expose name arguments @@ -10025,8 +10076,14 @@ use strict arg value return self~floor(value + .5) +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: XPathLocationPath */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + -- a multi-step path to a given location -::class "LocationPath" +::class "XPathLocationPath" ::method init expose steps use strict arg steps @@ -10046,6 +10103,12 @@ return nodeSet +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: XPathParser */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + -- the expression parser, which builds a location path that can be used to -- evaluate the xpath expression ::class "XPathParser" @@ -10154,26 +10217,26 @@ -- a wild card, this is easy if token == .XPathToken~wildcard then do -- looking for element nodes, matching anything - return .NodeTest~new(Node~ELEMENT_NODE, .QName~new("*", "*")) + return .XPathNodeTest~new(Node~ELEMENT_NODE, .QName~new("*", "*")) end -- some sort of node type test else if token~type == "NODETYPE" then do - if token~value = "element" then return .NodeTest~new(.Node~ELEMENT_NODE) - if token~value = "text" then return .NodeTest~new(.Node~TEXT_NODE) - if token~value = "comment" then return .NodeTest~new(.Node~COMMENT_NODE) - if token~value = "node" then return .NodeTest~new(.Node~ANY_NODE) - if token~value = "processing-instruction" then return .NodeTest~new(.Node~PROCESSING_INSTRUCTION_NODE) + if token~value = "element" then return .XPathNodeTest~new(.Node~ELEMENT_NODE) + if token~value = "text" then return .XPathNodeTest~new(.Node~TEXT_NODE) + if token~value = "comment" then return .XPathNodeTest~new(.Node~COMMENT_NODE) + if token~value = "node" then return .XPathNodeTest~new(.Node~ANY_NODE) + if token~value = "processing-instruction" then return .XPathNodeTest~new(.Node~PROCESSING_INSTRUCTION_NODE) end -- have a qualified name...all of the pieces are here already else if token~type == "QNAME" then do - return .NodeTest~new(Node~ANY_NODE, .QName~new(token~prefix, token~name)) + return .XPathNodeTest~new(Node~ANY_NODE, .QName~new(token~prefix, token~name)) end -- simple name token? else if token~type == "NCNAME" then - return .NodeTest~new(Node~ANY_NODE, .QName~new("*", token~name)) + return .XPathNodeTest~new(Node~ANY_NODE, .QName~new("*", token~name)) -- this token is something else...push it back and just return an ANY_NODE selector tokenqueue~previousToken - return .NodeTest~new(Node~ANY_NODE); + return .XPathNodeTest~new(Node~ANY_NODE); -- parse out a predicate ::method parsePredicate @@ -10374,7 +10437,7 @@ invalidIteratorState = .false -- make sure we have a good type - self~validateType(type) + self~class~validateType(type) if resultObject == .nil then .XpathException~raiseError(.XPathException~INVALID_EXPRESSION_ERR) @@ -10507,7 +10570,7 @@ return node -- validate the provided type -::method validateType private +::method validateType class use strict arg type if type \== self~ANY_TYPE & - @@ -10742,6 +10805,48 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ +/* Class: XPathExpressionImpl */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + +-- the implementation of the XPathExpression class +::class "XPathExpressionImpl" inherit XPathExpression +::method init + expose path document + use strict arg path, document = .nil + +-- evaluate the expression using the given context +::method evaluate + expose path document + use strict arg context, type = (.XPathResult~ANY_TYPE), resultObject = .nil + + -- we only support the castable XPathEvaluator, so the documents must match + if context \== document, context~ownerDocument \== document then + .DomException~raiseError(.DomException~WRONG_DOCUMENT_ERROR) + + -- context nodes are restricted to a small subset + nodeType = context~nodeType + if nodeType \= .Node~DOCUMENT_NODE & - + nodeType \= .Node~ELEMENT_NODE & - + nodeType \= .Node~ATTRIBUTE_NODE & - + nodeType \= .Node~TEXT_NODE & - + nodeType \= .Node~CDATA_SECTION_NODE & - + nodeType \= .Node~COMMENT_NODE & - + nodeType \= .Node~PROCESSING_INSTRUCTION_NODE & - + nodeType \= .XPathNamespace~XPATH_NAMESPACE_NODE then + .DomException~raiseError(.DomException~NOT_SUPPORTED_ERROR) + + -- validate that we have a valid type + .XPathResultImpl~validateType(type) + + -- evaluate the expression in the current context + res = path~evaluate(contextNode, .nil) + -- we always return a new object instance + return .XPathResultImpl(type, res, contextNode, path) + + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ /* Class: XMLCHAR */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |