diff options
| author | Gerd Moellmann | 2000-12-22 12:20:46 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 2000-12-22 12:20:46 +0000 |
| commit | 653558a1dcd19648e6a658034b6327a1f2fd701b (patch) | |
| tree | 0e292fde105212dd2d2f5781f8631c44ccf0ba6d | |
| parent | 9436cdf9a606ffcb470b86a1e3b39684a4e8b0d2 (diff) | |
| download | emacs-653558a1dcd19648e6a658034b6327a1f2fd701b.tar.gz emacs-653558a1dcd19648e6a658034b6327a1f2fd701b.zip | |
(top level comment): Updated to reflect the fact that
white spaces are relevant in the XML file
(xml-parse-file): Do not kill an existing Emacs buffer if the file
to parse was already edited. This allows for on-the-fly analysis
of XML files
(xml-parse-tag): Check that the casing is the same in the start
tag and end tag, since XML is case-sensitive. Allows for spaces
in the end tag, after the name of the tag.
(xml-parse-attlist): Allow for the character '-' in the name of
attributes, as in the standard http-equiv attribute Do not save
the properties in the XML tree, since they are not relevant
| -rw-r--r-- | lisp/ChangeLog | 14 | ||||
| -rw-r--r-- | lisp/xml.el | 40 |
2 files changed, 40 insertions, 14 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index bd9b2e31406..645f106e73f 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,17 @@ | |||
| 1 | 2000-08-22 Emmanuel Briot <briot@gnat.com> | ||
| 2 | |||
| 3 | * xml.el (top level comment): Updated to reflect the fact that | ||
| 4 | white spaces are relevant in the XML file | ||
| 5 | (xml-parse-file): Do not kill an existing Emacs buffer if the file | ||
| 6 | to parse was already edited. This allows for on-the-fly analysis | ||
| 7 | of XML files | ||
| 8 | (xml-parse-tag): Check that the casing is the same in the start | ||
| 9 | tag and end tag, since XML is case-sensitive. Allows for spaces | ||
| 10 | in the end tag, after the name of the tag. | ||
| 11 | (xml-parse-attlist): Allow for the character '-' in the name of | ||
| 12 | attributes, as in the standard http-equiv attribute Do not save | ||
| 13 | the properties in the XML tree, since they are not relevant | ||
| 14 | |||
| 1 | 2000-12-21 Stefan Monnier <monnier@cs.yale.edu> | 15 | 2000-12-21 Stefan Monnier <monnier@cs.yale.edu> |
| 2 | 16 | ||
| 3 | * generic.el (generic-read-type): Undo last change, inline into | 17 | * generic.el (generic-read-type): Undo last change, inline into |
diff --git a/lisp/xml.el b/lisp/xml.el index a7d2ba48ef5..25851e2a9ea 100644 --- a/lisp/xml.el +++ b/lisp/xml.el | |||
| @@ -39,9 +39,9 @@ | |||
| 39 | ;; in the XML file. | 39 | ;; in the XML file. |
| 40 | ;; | 40 | ;; |
| 41 | ;; The XML file should have the following format: | 41 | ;; The XML file should have the following format: |
| 42 | ;; <node1 attr1="name1" attr2="name2" ...> value | 42 | ;; <node1 attr1="name1" attr2="name2" ...>value |
| 43 | ;; <node2 attr3="name3" attr4="name4"> value2 </node2> | 43 | ;; <node2 attr3="name3" attr4="name4">value2</node2> |
| 44 | ;; <node3 attr5="name5" attr6="name6"> value3 </node3> | 44 | ;; <node3 attr5="name5" attr6="name6">value3</node3> |
| 45 | ;; </node1> | 45 | ;; </node1> |
| 46 | ;; Of course, the name of the nodes and attributes can be anything. There can | 46 | ;; Of course, the name of the nodes and attributes can be anything. There can |
| 47 | ;; be any number of attributes (or none), as well as any number of children | 47 | ;; be any number of attributes (or none), as well as any number of children |
| @@ -118,15 +118,24 @@ An empty string is returned if the attribute was not found." | |||
| 118 | 118 | ||
| 119 | (defun xml-parse-file (file &optional parse-dtd) | 119 | (defun xml-parse-file (file &optional parse-dtd) |
| 120 | "Parse the well-formed XML FILE. | 120 | "Parse the well-formed XML FILE. |
| 121 | If FILE is already edited, this will keep the buffer alive. | ||
| 121 | Returns the top node with all its children. | 122 | Returns the top node with all its children. |
| 122 | If PARSE-DTD is non-nil, the DTD is parsed rather than skipped." | 123 | If PARSE-DTD is non-nil, the DTD is parsed rather than skipped." |
| 123 | (find-file file) | 124 | (let ((keep)) |
| 124 | (let ((xml (xml-parse-region (point-min) | 125 | (if (get-file-buffer file) |
| 125 | (point-max) | 126 | (progn |
| 126 | (current-buffer) | 127 | (set-buffer (get-file-buffer file)) |
| 127 | parse-dtd))) | 128 | (setq keep (point))) |
| 128 | (kill-buffer (current-buffer)) | 129 | (find-file file)) |
| 129 | xml)) | 130 | |
| 131 | (let ((xml (xml-parse-region (point-min) | ||
| 132 | (point-max) | ||
| 133 | (current-buffer) | ||
| 134 | parse-dtd))) | ||
| 135 | (if keep | ||
| 136 | (goto-char keep) | ||
| 137 | (kill-buffer (current-buffer))) | ||
| 138 | xml))) | ||
| 130 | 139 | ||
| 131 | (defun xml-parse-region (beg end &optional buffer parse-dtd) | 140 | (defun xml-parse-region (beg end &optional buffer parse-dtd) |
| 132 | "Parse the region from BEG to END in BUFFER. | 141 | "Parse the region from BEG to END in BUFFER. |
| @@ -206,6 +215,7 @@ Returns one of: | |||
| 206 | ((looking-at "<\\([^/> \t\n]+\\)") | 215 | ((looking-at "<\\([^/> \t\n]+\\)") |
| 207 | (let* ((node-name (match-string 1)) | 216 | (let* ((node-name (match-string 1)) |
| 208 | (children (list (intern node-name))) | 217 | (children (list (intern node-name))) |
| 218 | (case-fold-search nil) ;; XML is case-sensitive | ||
| 209 | pos) | 219 | pos) |
| 210 | (goto-char (match-end 1)) | 220 | (goto-char (match-end 1)) |
| 211 | 221 | ||
| @@ -224,13 +234,15 @@ Returns one of: | |||
| 224 | (progn | 234 | (progn |
| 225 | (forward-char 1) | 235 | (forward-char 1) |
| 226 | (skip-chars-forward " \t\n") | 236 | (skip-chars-forward " \t\n") |
| 227 | (while (not (looking-at (concat "</" node-name ">"))) | 237 | ;; Now check that we have the right end-tag. Note that this one might |
| 238 | ;; contain spaces after the tag name | ||
| 239 | (while (not (looking-at (concat "</" node-name "[ \t\n]*>"))) | ||
| 228 | (cond | 240 | (cond |
| 229 | ((looking-at "</") | 241 | ((looking-at "</") |
| 230 | (error (concat | 242 | (error (concat |
| 231 | "XML: invalid syntax -- invalid end tag (expecting " | 243 | "XML: invalid syntax -- invalid end tag (expecting " |
| 232 | node-name | 244 | node-name |
| 233 | ")"))) | 245 | ") at pos " (number-to-string (point))))) |
| 234 | ((= (char-after) ?<) | 246 | ((= (char-after) ?<) |
| 235 | (set 'children (append children (list (xml-parse-tag end))))) | 247 | (set 'children (append children (list (xml-parse-tag end))))) |
| 236 | (t | 248 | (t |
| @@ -269,7 +281,7 @@ Leaves the point on the first non-blank character after the tag." | |||
| 269 | (let ((attlist '()) | 281 | (let ((attlist '()) |
| 270 | name) | 282 | name) |
| 271 | (skip-chars-forward " \t\n") | 283 | (skip-chars-forward " \t\n") |
| 272 | (while (looking-at "\\([a-zA-Z_:][a-zA-Z0-9.-_:]*\\)[ \t\n]*=[ \t\n]*") | 284 | (while (looking-at "\\([a-zA-Z_:][-a-zA-Z0-9._:]*\\)[ \t\n]*=[ \t\n]*") |
| 273 | (set 'name (intern (match-string 1))) | 285 | (set 'name (intern (match-string 1))) |
| 274 | (goto-char (match-end 0)) | 286 | (goto-char (match-end 0)) |
| 275 | 287 | ||
| @@ -284,7 +296,7 @@ Leaves the point on the first non-blank character after the tag." | |||
| 284 | (error "XML: each attribute must be unique within an element.")) | 296 | (error "XML: each attribute must be unique within an element.")) |
| 285 | 297 | ||
| 286 | (set 'attlist (append attlist | 298 | (set 'attlist (append attlist |
| 287 | (list (cons name (match-string 1))))) | 299 | (list (cons name (match-string-no-properties 1))))) |
| 288 | (goto-char (match-end 0)) | 300 | (goto-char (match-end 0)) |
| 289 | (skip-chars-forward " \t\n") | 301 | (skip-chars-forward " \t\n") |
| 290 | (if (> (point) end) | 302 | (if (> (point) end) |