184 |
;; beginning of a document) |
;; beginning of a document) |
185 |
((looking-at "<\\?") |
((looking-at "<\\?") |
186 |
(search-forward "?>" end) |
(search-forward "?>" end) |
187 |
(skip-chars-forward " \t\n") |
(goto-char (- (re-search-forward "[^[:space:]]") 1)) |
188 |
(xml-parse-tag end)) |
(xml-parse-tag end)) |
189 |
;; Character data (CDATA) sections, in which no tag should be interpreted |
;; Character data (CDATA) sections, in which no tag should be interpreted |
190 |
((looking-at "<!\\[CDATA\\[") |
((looking-at "<!\\[CDATA\\[") |
198 |
(if parse-dtd |
(if parse-dtd |
199 |
(setq dtd (xml-parse-dtd end)) |
(setq dtd (xml-parse-dtd end)) |
200 |
(xml-skip-dtd end)) |
(xml-skip-dtd end)) |
201 |
(skip-chars-forward " \t\n") |
(goto-char (- (re-search-forward "[^[:space:]]") 1)) |
202 |
(if dtd |
(if dtd |
203 |
(cons dtd (xml-parse-tag end)) |
(cons dtd (xml-parse-tag end)) |
204 |
(xml-parse-tag end)))) |
(xml-parse-tag end)))) |
210 |
((looking-at "</") |
((looking-at "</") |
211 |
'()) |
'()) |
212 |
;; opening tag |
;; opening tag |
213 |
((looking-at "<\\([^/> \t\n]+\\)") |
((looking-at "<\\([^/>[:space:]]+\\)") |
214 |
(goto-char (match-end 1)) |
(goto-char (match-end 1)) |
215 |
(let* ((case-fold-search nil) ;; XML is case-sensitive. |
(let* ((case-fold-search nil) ;; XML is case-sensitive. |
216 |
(node-name (match-string 1)) |
(node-name (match-string 1)) |
219 |
pos) |
pos) |
220 |
|
|
221 |
;; is this an empty element ? |
;; is this an empty element ? |
222 |
(if (looking-at "/[ \t\n]*>") |
(if (looking-at "/[[:space:]]*>") |
223 |
(progn |
(progn |
224 |
(forward-char 2) |
(forward-char 2) |
225 |
(nreverse (cons '("") children))) |
(nreverse (cons '("") children))) |
230 |
(forward-char 1) |
(forward-char 1) |
231 |
;; Now check that we have the right end-tag. Note that this |
;; Now check that we have the right end-tag. Note that this |
232 |
;; one might contain spaces after the tag name |
;; one might contain spaces after the tag name |
233 |
(while (not (looking-at (concat "</" node-name "[ \t\n]*>"))) |
(while (not (looking-at (concat "</" node-name "[[:space:]]*>"))) |
234 |
(cond |
(cond |
235 |
((looking-at "</") |
((looking-at "</") |
236 |
(error (concat |
(error (concat |
281 |
Leaves the point on the first non-blank character after the tag." |
Leaves the point on the first non-blank character after the tag." |
282 |
(let ((attlist ()) |
(let ((attlist ()) |
283 |
name) |
name) |
284 |
(skip-chars-forward " \t\n") |
(goto-char (- (re-search-forward "[^[:space:]]") 1)) |
285 |
(while (looking-at "\\([a-zA-Z_:][-a-zA-Z0-9._:]*\\)[ \t\n]*=[ \t\n]*") |
(while (looking-at "\\([a-zA-Z_:][-a-zA-Z0-9._:]*\\)[[:space:]]*=[[:space:]]*") |
286 |
(setq name (intern (match-string 1))) |
(setq name (intern (match-string 1))) |
287 |
(goto-char (match-end 0)) |
(goto-char (match-end 0)) |
288 |
|
|
298 |
|
|
299 |
(push (cons name (match-string-no-properties 1)) attlist) |
(push (cons name (match-string-no-properties 1)) attlist) |
300 |
(goto-char (match-end 0)) |
(goto-char (match-end 0)) |
301 |
(skip-chars-forward " \t\n") |
(goto-char (- (re-search-forward "[^[:space:]]") 1)) |
302 |
(if (> (point) end) |
(if (> (point) end) |
303 |
(error "XML: end of attribute list not found before end of region")) |
(error "XML: end of attribute list not found before end of region")) |
304 |
) |
) |
318 |
The point must be just before the starting tag of the DTD. |
The point must be just before the starting tag of the DTD. |
319 |
This follows the rule [28] in the XML specifications." |
This follows the rule [28] in the XML specifications." |
320 |
(forward-char (length "<!DOCTYPE")) |
(forward-char (length "<!DOCTYPE")) |
321 |
(if (looking-at "[ \t\n]*>") |
(if (looking-at "[[:space:]]*>") |
322 |
(error "XML: invalid DTD (excepting name of the document)")) |
(error "XML: invalid DTD (excepting name of the document)")) |
323 |
(condition-case nil |
(condition-case nil |
324 |
(progn |
(progn |
325 |
(forward-word 1) ;; name of the document |
(forward-word 1) ;; name of the document |
326 |
(skip-chars-forward " \t\n") |
(goto-char (- (re-search-forward "[^[:space:]]") 1)) |
327 |
(if (looking-at "\\[") |
(if (looking-at "\\[") |
328 |
(re-search-forward "\\][ \t\n]*>" end) |
(re-search-forward "\\][[:space:]]*>" end) |
329 |
(search-forward ">" end))) |
(search-forward ">" end))) |
330 |
(error (error "XML: No end to the DTD")))) |
(error (error "XML: No end to the DTD")))) |
331 |
|
|
333 |
"Parse the DTD that point is looking at. |
"Parse the DTD that point is looking at. |
334 |
The DTD must end before the position END in the current buffer." |
The DTD must end before the position END in the current buffer." |
335 |
(forward-char (length "<!DOCTYPE")) |
(forward-char (length "<!DOCTYPE")) |
336 |
(skip-chars-forward " \t\n") |
(goto-char (- (re-search-forward "[^[:space:]]") 1)) |
337 |
(if (looking-at ">") |
(if (looking-at ">") |
338 |
(error "XML: invalid DTD (excepting name of the document)")) |
(error "XML: invalid DTD (excepting name of the document)")) |
339 |
|
|
343 |
type element end-pos) |
type element end-pos) |
344 |
(goto-char (match-end 0)) |
(goto-char (match-end 0)) |
345 |
|
|
346 |
(skip-chars-forward " \t\n") |
(goto-char (- (re-search-forward "[^[:space:]]") 1)) |
347 |
|
|
348 |
;; External DTDs => don't know how to handle them yet |
;; External DTDs => don't know how to handle them yet |
349 |
(if (looking-at "SYSTEM") |
(if (looking-at "SYSTEM") |
354 |
|
|
355 |
;; Parse the rest of the DTD |
;; Parse the rest of the DTD |
356 |
(forward-char 1) |
(forward-char 1) |
357 |
(while (and (not (looking-at "[ \t\n]*\\]")) |
(while (and (not (looking-at "[[:space:]]*\\]")) |
358 |
(<= (point) end)) |
(<= (point) end)) |
359 |
(cond |
(cond |
360 |
|
|
361 |
;; Translation of rule [45] of XML specifications |
;; Translation of rule [45] of XML specifications |
362 |
((looking-at |
((looking-at |
363 |
"[\t \n]*<!ELEMENT[ \t\n]+\\([a-zA-Z0-9.%;]+\\)[ \t\n]+\\([^>]+\\)>") |
"[[:space:]]*<!ELEMENT[[:space:]]+\\([a-zA-Z0-9.%;]+\\)[[:space:]]+\\([^>]+\\)>") |
364 |
|
|
365 |
(setq element (intern (match-string-no-properties 1)) |
(setq element (intern (match-string-no-properties 1)) |
366 |
type (match-string-no-properties 2)) |
type (match-string-no-properties 2)) |
368 |
|
|
369 |
;; Translation of rule [46] of XML specifications |
;; Translation of rule [46] of XML specifications |
370 |
(cond |
(cond |
371 |
((string-match "^EMPTY[ \t\n]*$" type) ;; empty declaration |
((string-match "^EMPTY[[:space:]]*$" type) ;; empty declaration |
372 |
(setq type 'empty)) |
(setq type 'empty)) |
373 |
((string-match "^ANY[ \t\n]*$" type) ;; any type of contents |
((string-match "^ANY[[:space:]]*$" type) ;; any type of contents |
374 |
(setq type 'any)) |
(setq type 'any)) |
375 |
((string-match "^(\\(.*\\))[ \t\n]*$" type) ;; children ([47]) |
((string-match "^(\\(.*\\))[[:space:]]*$" type) ;; children ([47]) |
376 |
(setq type (xml-parse-elem-type (match-string-no-properties 1 type)))) |
(setq type (xml-parse-elem-type (match-string-no-properties 1 type)))) |
377 |
((string-match "^%[^;]+;[ \t\n]*$" type) ;; substitution |
((string-match "^%[^;]+;[[:space:]]*$" type) ;; substitution |
378 |
nil) |
nil) |
379 |
(t |
(t |
380 |
(error "XML: Invalid element type in the DTD"))) |
(error "XML: Invalid element type in the DTD"))) |
416 |
(mapcar 'xml-parse-elem-type |
(mapcar 'xml-parse-elem-type |
417 |
(split-string elem ",")))) |
(split-string elem ",")))) |
418 |
))) |
))) |
419 |
(if (string-match "[ \t\n]*\\([^+*?]+\\)\\([+*?]?\\)" string) |
(if (string-match "[[:space:]]*\\([^+*?]+\\)\\([+*?]?\\)" string) |
420 |
(setq elem (match-string 1 string) |
(setq elem (match-string 1 string) |
421 |
modifier (match-string 2 string)))) |
modifier (match-string 2 string)))) |
422 |
|
|