86361
|
1 ;;; nxml-ns.el --- XML namespace processing
|
|
2
|
|
3 ;; Copyright (C) 2003 Free Software Foundation, Inc.
|
|
4
|
|
5 ;; Author: James Clark
|
|
6 ;; Keywords: XML
|
|
7
|
|
8 ;; This program is free software; you can redistribute it and/or
|
|
9 ;; modify it under the terms of the GNU General Public License as
|
|
10 ;; published by the Free Software Foundation; either version 2 of
|
|
11 ;; the License, or (at your option) any later version.
|
|
12
|
|
13 ;; This program is distributed in the hope that it will be
|
|
14 ;; useful, but WITHOUT ANY WARRANTY; without even the implied
|
|
15 ;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
16 ;; PURPOSE. See the GNU General Public License for more details.
|
|
17
|
|
18 ;; You should have received a copy of the GNU General Public
|
|
19 ;; License along with this program; if not, write to the Free
|
|
20 ;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
21 ;; MA 02111-1307 USA
|
|
22
|
|
23 ;;; Commentary:
|
|
24
|
|
25 ;; This file uses a prefix of `nxml-ns'.
|
|
26
|
|
27 ;;; Code:
|
|
28
|
|
29 (require 'nxml-util)
|
|
30
|
|
31 (defvar nxml-ns-state nil
|
|
32 "Contains the state of namespace processing. The state
|
|
33 is never modified destructively and so can be saved and restored
|
|
34 without copying.
|
|
35
|
|
36 The value is a stack represented by a list. The list has length N + 1
|
|
37 where N is the number of open elements. Each member of the list
|
|
38 represents the bindings in effect for a particular element. Each
|
|
39 member is itself a list whose car is the default namespace
|
|
40 \(a symbol or nil) and whose cdr is an alist of (PREFIX . NS) pairs
|
|
41 where PREFIX is a string (never nil) and NS is the namespace URI
|
|
42 symbol.")
|
|
43
|
|
44 (defconst nxml-ns-initial-state
|
|
45 (list (list nil (cons "xml" nxml-xml-namespace-uri)))
|
|
46 "A list to be used as the initial value of nxml-ns-state. This
|
|
47 represents the state with no open elements and with the default
|
|
48 namespace bindings (no default namespace and only the xml prefix bound).")
|
|
49
|
|
50 (defsubst nxml-ns-state () nxml-ns-state)
|
|
51
|
|
52 (defsubst nxml-ns-set-state (state)
|
|
53 (setq nxml-ns-state state))
|
|
54
|
|
55 (defsubst nxml-ns-state-equal (state)
|
|
56 (equal nxml-ns-state state))
|
|
57
|
|
58 (defmacro nxml-ns-save (&rest body)
|
|
59 `(let ((nxml-ns-state nxml-ns-initial-state))
|
|
60 ,@body))
|
|
61
|
|
62 (put 'nxml-ns-save 'lisp-indent-function 0)
|
|
63 (def-edebug-spec nxml-ns-save t)
|
|
64
|
|
65 (defun nxml-ns-init ()
|
|
66 (setq nxml-ns-state nxml-ns-initial-state))
|
|
67
|
|
68 (defun nxml-ns-push-state ()
|
|
69 "Change the state by starting a new element. Namespace declarations
|
|
70 are inherited from the parent state."
|
|
71 (setq nxml-ns-state (cons (car nxml-ns-state) nxml-ns-state)))
|
|
72
|
|
73 (defun nxml-ns-pop-state ()
|
|
74 "Change the state by ending an element. The behaviour is undefined
|
|
75 if there is no open element."
|
|
76 (setq nxml-ns-state (cdr nxml-ns-state)))
|
|
77
|
|
78 (defun nxml-ns-get-prefix (prefix)
|
|
79 "Return the symbol for namespace bound to PREFIX, or nil if PREFIX
|
|
80 is unbound. PREFIX is a string, never nil."
|
|
81 (let ((binding (assoc prefix (cdar nxml-ns-state))))
|
|
82 (and binding (cdr binding))))
|
|
83
|
|
84 (defun nxml-ns-set-prefix (prefix ns)
|
|
85 "Change the binding of PREFIX. PREFIX is a string (never nil). NS
|
|
86 is a symbol (never nil). The change will be in effect until the end of
|
|
87 the current element."
|
|
88 (setq nxml-ns-state
|
|
89 (let ((bindings (car nxml-ns-state)))
|
|
90 (cons (cons (car bindings)
|
|
91 (cons (cons prefix ns) (cdr bindings)))
|
|
92 (cdr nxml-ns-state)))))
|
|
93
|
|
94 (defun nxml-ns-get-default ()
|
|
95 "Return the current default namespace as a symbol, or nil
|
|
96 if there is no default namespace."
|
|
97 (caar nxml-ns-state))
|
|
98
|
|
99 (defun nxml-ns-set-default (ns)
|
|
100 "Changes the current default namespace. The change
|
|
101 will be in effect until the end of the current element.
|
|
102 NS is a symbol or nil."
|
|
103 (setq nxml-ns-state
|
|
104 (cons (cons ns (cdar nxml-ns-state))
|
|
105 (cdr nxml-ns-state))))
|
|
106
|
|
107 (defun nxml-ns-get-context ()
|
|
108 (car nxml-ns-state))
|
|
109
|
|
110 (defun nxml-ns-prefixes-for (ns &optional attributep)
|
|
111 (let ((current (car nxml-ns-state))
|
|
112 prefixes)
|
|
113 (when (if attributep
|
|
114 (not ns)
|
|
115 (eq (car current) ns))
|
|
116 (setq prefixes '(nil)))
|
|
117 (setq current (cdr current))
|
|
118 (while (let ((binding (rassq ns current)))
|
|
119 (when binding
|
|
120 (when (eq (nxml-ns-get-prefix (car binding)) ns)
|
|
121 (add-to-list 'prefixes
|
|
122 (car binding)))
|
|
123 (setq current
|
|
124 (cdr (member binding current))))))
|
|
125 prefixes))
|
|
126
|
|
127 (defun nxml-ns-prefix-for (ns)
|
|
128 (car (rassq ns (cdar nxml-ns-state))))
|
|
129
|
|
130 (defun nxml-ns-changed-prefixes ()
|
|
131 (let ((old (cadr nxml-ns-state))
|
|
132 (new (car nxml-ns-state))
|
|
133 changed)
|
|
134 (if (eq old new)
|
|
135 nil
|
|
136 (unless (eq (car new) (car old))
|
|
137 (setq changed '(nil)))
|
|
138 (setq new (cdr new))
|
|
139 (setq old (cdr old))
|
|
140 (while (not (eq new old))
|
|
141 (setq changed
|
|
142 (cons (caar new) changed))
|
|
143 (setq new (cdr new))))
|
|
144 changed))
|
|
145
|
|
146 (provide 'nxml-ns)
|
|
147
|
|
148 ;;; nxml-ns.el ends here
|