From c1ebba6f0865a246ce05f853688a90c70a7884c1 Mon Sep 17 00:00:00 2001 From: David Lichteblau Date: Sat, 26 Apr 2008 16:24:11 +0200 Subject: [PATCH] Fixed multiple keys --- TEST | 19 +++++------------- test.lisp | 6 +++++- xslt.lisp | 67 ++++++++++++++++++++++++++++++++++----------------------------- 3 files changed, 46 insertions(+), 46 deletions(-) diff --git a/TEST b/TEST index b13a0a1..cfa0242 100644 --- a/TEST +++ b/TEST @@ -13555,7 +13555,7 @@ PASS Include__77514 [XSLT-Structure]: raised an xslt-error as expected Actual output: MSFT_Conformance_Tests/Include/Include__77514.xuriella WARNING: There is no such encoding: "shift_jis". -FAIL Include__77515 [XSLT-Structure]: cannot parse stylesheet: Document not well-formed: Corrupted UTF-8 input (initial byte was #b10000010) +KNOWNFAIL Include__77515 [XSLT-Structure]: cannot parse stylesheet: Document not well-formed: Corrupted UTF-8 input (initial byte was #b10000010) Location: Line 1, column 44 in file://+...MSFT_Conformance_Tests/Include/XSLT03022a.xsl @@ -13565,14 +13565,6 @@ Location: Expected output (1): MSFT_Conformance_Tests/Include/Include__77515.saxon Actual output: MSFT_Conformance_Tests/Include/Include__77515.xuriella -FAIL Include__77736 [XSLT-Structure]: condition of incorrect type: -error opening #P"...MSFT_Conformance_Tests/Include/xslt03022.noindent-xsl": - No such file or directory - Stylesheet: MSFT_Conformance_Tests/Include/xslt03022.noindent-xsl - Data: MSFT_Conformance_Tests/Include/books.xml - Expected output (1): MSFT_Conformance_Tests/Include/Include__77736.saxon - Actual output: MSFT_Conformance_Tests/Include/Include__77736.xuriella - PASS Include__77745 [XSLT-Structure]: raised an xslt-error as expected Stylesheet: MSFT_Conformance_Tests/Include/xslt03019.noindent-xsl Data: MSFT_Conformance_Tests/Include/books.xml @@ -13728,8 +13720,7 @@ PASS Keys_SortNodesetReturnedByKey [XSLT-Data-Manipulation] Expected output (1): MSFT_Conformance_Tests/Keys/Keys_SortNodesetReturnedByKey.saxon Actual output: MSFT_Conformance_Tests/Keys/Keys_SortNodesetReturnedByKey.xuriella -FAIL Keys_MultipltKeysInclude [XSLT-Data-Manipulation]: duplicate key: (prices - . ) +PASS Keys_MultipltKeysInclude [XSLT-Data-Manipulation] Stylesheet: MSFT_Conformance_Tests/Keys/MultipltKeysInclude.noindent-xsl Data: MSFT_Conformance_Tests/Keys/MultipltKeysInclude.xml Supplemental stylesheet: MSFT_Conformance_Tests/Keys/MultipltKeysInclude.inc @@ -13924,7 +13915,7 @@ PASS Keys__91835 [XSLT-Data-Manipulation] Expected output (1): MSFT_Conformance_Tests/Keys/Keys__91835.saxon Actual output: MSFT_Conformance_Tests/Keys/Keys__91835.xuriella -FAIL Keys__91836 [XSLT-Data-Manipulation]: duplicate key: (foo . ) +PASS Keys__91836 [XSLT-Data-Manipulation] Stylesheet: MSFT_Conformance_Tests/Keys/91836.noindent-xsl Data: MSFT_Conformance_Tests/Keys/91836.xml Expected output (1): MSFT_Conformance_Tests/Keys/Keys__91836.saxon @@ -13936,7 +13927,7 @@ PASS Keys__91858 [XSLT-Data-Manipulation] Expected output (1): MSFT_Conformance_Tests/Keys/Keys__91858.saxon Actual output: MSFT_Conformance_Tests/Keys/Keys__91858.xuriella -FAIL Keys__91859 [XSLT-Data-Manipulation]: duplicate key: (foo . ) +PASS Keys__91859 [XSLT-Data-Manipulation] Stylesheet: MSFT_Conformance_Tests/Keys/91859.noindent-xsl Data: MSFT_Conformance_Tests/Keys/91859.xml Expected output (1): MSFT_Conformance_Tests/Keys/Keys__91859.saxon @@ -19382,4 +19373,4 @@ PASS XSLTFunctions_DocumentFuncWithEmptyArg [Mixed] Expected output (1): MSFT_Conformance_Tests/XSLTFunctions/XSLTFunctions_DocumentFuncWithEmptyArg.saxon Actual output: MSFT_Conformance_Tests/XSLTFunctions/XSLTFunctions_DocumentFuncWithEmptyArg.xuriella -Passed 2935/3080 tests (3 expected failures, 142 unexpected failures). +Passed 2938/3079 tests (4 expected failures, 137 unexpected failures). diff --git a/test.lisp b/test.lisp index cb8a819..2fff998 100644 --- a/test.lisp +++ b/test.lisp @@ -342,7 +342,8 @@ "Keys_PerfRepro3" ;; test stylesheet doesn't exist?! - "ConflictResolution__77833")) + "ConflictResolution__77833" + "Include__77736")) ;; Tests where the output isn't a match because of extraneous whitespace. ;; For these tests, we force space normalization before comparing. @@ -378,6 +379,9 @@ ;; uses KOI, which Babel doesn't support "BVTs_bvt019" + ;; shift_jis + "Include__77515" + ;; FIXME? ;; ;; This is an HTML output method issue. The spec says the HTML diff --git a/xslt.lisp b/xslt.lisp index 7fe2dda..c8194cf 100644 --- a/xslt.lisp +++ b/xslt.lisp @@ -464,10 +464,8 @@ (defun key-use (key) (cdr key)) (defun add-key (stylesheet name match use) - (if (gethash name (stylesheet-keys stylesheet)) - (xslt-error "duplicate key: ~a" name) - (setf (gethash name (stylesheet-keys stylesheet)) - (make-key match use)))) + (push (make-key match use) + (gethash name (stylesheet-keys stylesheet)))) (defvar *excluded-namespaces* (list *xsl*)) (defvar *empty-mode*) @@ -651,7 +649,7 @@ (xpath:evaluate "preceding-sibling::*" import t)))) - (and prev (not (namep (stp:local-name prev) "import")))) + (and prev (not (namep prev "import")))) (xslt-error "import not at beginning of stylesheet")) (let ((uri (puri:merge-uris (or (stp:attribute-value import "href") (xslt-error "import without href")) @@ -1287,6 +1285,10 @@ object) (list (%document (xpath:string-value object) base-uri)))))))) +;; FIXME: the point of keys is that we are meant to optimize this +;; by building a table mapping nodes to values for each key. +;; We should run over all matching nodes and store them in such a table +;; when seeing their document for the first time. (xpath-sys:define-xpath-function/lazy xslt :key (name object) (let ((namespaces *namespaces*)) (lambda (ctx) @@ -1296,28 +1298,33 @@ (multiple-value-bind (local-name uri) (decode-qname/runtime qname namespaces nil) (cons local-name uri))) - (key (find-key expanded-name *stylesheet*))) - (labels ((get-by-key (value) - (let ((value (xpath:string-value value))) - (xpath::filter-pipe - #'(lambda (node) - (let ((uses - (xpath:evaluate-compiled (key-use key) node))) - (if (xpath:node-set-p uses) - (xpath::find-in-pipe - value - (xpath-sys:pipe-of uses) - :key #'xpath:string-value - :test #'equal) - (equal value (xpath:string-value uses))))) - (xpath-sys:pipe-of - (xpath:node-set-value - (xpath:evaluate-compiled (key-match key) ctx))))))) - (xpath-sys:make-node-set - (xpath::sort-pipe - (if (xpath:node-set-p object) - (xpath::mappend-pipe #'get-by-key (xpath-sys:pipe-of object)) - (get-by-key object))))))))) + (key-conses (find-key expanded-name *stylesheet*))) + (xpath-sys:make-node-set + (xpath::mappend-pipe + (lambda (key) + (labels ((get-by-key (value) + (let ((value (xpath:string-value value))) + (xpath::filter-pipe + #'(lambda (node) + (let ((uses + (xpath:evaluate-compiled (key-use key) + node))) + (if (xpath:node-set-p uses) + (xpath::find-in-pipe + value + (xpath-sys:pipe-of uses) + :key #'xpath:string-value + :test #'equal) + (equal value (xpath:string-value uses))))) + (xpath-sys:pipe-of + (xpath:node-set-value + (xpath:evaluate-compiled (key-match key) ctx))))))) + (xpath::sort-pipe + (if (xpath:node-set-p object) + (xpath::mappend-pipe #'get-by-key + (xpath-sys:pipe-of object)) + (get-by-key object))))) + key-conses)))))) ;; FIXME: add alias mechanism for XPath extensions in order to avoid duplication @@ -1351,10 +1358,8 @@ highest-base-uri) while next finally (return highest-base-uri)))) - ;; Heuristic: Reverse it so that the /home/david/alwaysthesame prefix is - ;; checked only if everything else matches. - ;; - ;; This might be pointless premature optimization, but I like the idea :-) + ;; FIXME: Now that we intern documents, we could use a short ID for + ;; the document instead of the base URI. (nreverse (concatenate 'string highest-base-uri "//" id))))) (xpath-sys:define-xpath-function/lazy xslt :generate-id (&optional node-set-thunk) -- 2.11.4.GIT