aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/xml.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/xml.el')
-rw-r--r--lisp/xml.el86
1 files changed, 53 insertions, 33 deletions
diff --git a/lisp/xml.el b/lisp/xml.el
index 408c13ab39b..03ef6346c70 100644
--- a/lisp/xml.el
+++ b/lisp/xml.el
@@ -27,13 +27,13 @@
27 27
28;; This file contains a somewhat incomplete non-validating XML parser. It 28;; This file contains a somewhat incomplete non-validating XML parser. It
29;; parses a file, and returns a list that can be used internally by 29;; parses a file, and returns a list that can be used internally by
30;; any other lisp libraries. 30;; any other Lisp libraries.
31 31
32;;; FILE FORMAT 32;;; FILE FORMAT
33 33
34;; The document type declaration may either be ignored or (optionally) 34;; The document type declaration may either be ignored or (optionally)
35;; parsed, but currently the parsing will only accept element 35;; parsed, but currently the parsing will only accept element
36;; declarations. The XML file is assumed to be well-formed. In case 36;; declarations. The XML file is assumed to be well-formed. In case
37;; of error, the parsing stops and the XML file is shown where the 37;; of error, the parsing stops and the XML file is shown where the
38;; parsing stopped. 38;; parsing stopped.
39;; 39;;
@@ -44,7 +44,7 @@
44;; <node2 attr3="name3" attr4="name4">value2</node2> 44;; <node2 attr3="name3" attr4="name4">value2</node2>
45;; <node3 attr5="name5" attr6="name6">value3</node3> 45;; <node3 attr5="name5" attr6="name6">value3</node3>
46;; </node1> 46;; </node1>
47;; Of course, the name of the nodes and attributes can be anything. There can 47;; Of course, the name of the nodes and attributes can be anything. There can
48;; be any number of attributes (or none), as well as any number of children 48;; be any number of attributes (or none), as well as any number of children
49;; below the nodes. 49;; below the nodes.
50;; 50;;
@@ -86,7 +86,18 @@
86 86
87(defsubst xml-node-name (node) 87(defsubst xml-node-name (node)
88 "Return the tag associated with NODE. 88 "Return the tag associated with NODE.
89The tag is a lower-case symbol." 89Without namespace-aware parsing, the tag is a symbol.
90
91With namespace-aware parsing, the tag is a cons of a string
92representing the uri of the namespace with the local name of the
93tag. For example,
94
95 <foo>
96
97would be represented by
98
99 '(\"\" . \"foo\")."
100
90 (car node)) 101 (car node))
91 102
92(defsubst xml-node-attributes (node) 103(defsubst xml-node-attributes (node)
@@ -101,17 +112,17 @@ This is a list of nodes, and it can be nil."
101 112
102(defun xml-get-children (node child-name) 113(defun xml-get-children (node child-name)
103 "Return the children of NODE whose tag is CHILD-NAME. 114 "Return the children of NODE whose tag is CHILD-NAME.
104CHILD-NAME should be a lower case symbol." 115CHILD-NAME should match the value returned by `xml-node-name'."
105 (let ((match ())) 116 (let ((match ()))
106 (dolist (child (xml-node-children node)) 117 (dolist (child (xml-node-children node))
107 (if child 118 (if (and (listp child)
108 (if (equal (xml-node-name child) child-name) 119 (equal (xml-node-name child) child-name))
109 (push child match)))) 120 (push child match)))
110 (nreverse match))) 121 (nreverse match)))
111 122
112(defun xml-get-attribute-or-nil (node attribute) 123(defun xml-get-attribute-or-nil (node attribute)
113 "Get from NODE the value of ATTRIBUTE. 124 "Get from NODE the value of ATTRIBUTE.
114Return `nil' if the attribute was not found. 125Return nil if the attribute was not found.
115 126
116See also `xml-get-attribute'." 127See also `xml-get-attribute'."
117 (cdr (assoc attribute (xml-node-attributes node)))) 128 (cdr (assoc attribute (xml-node-attributes node))))
@@ -236,7 +247,8 @@ If PARSE-NS is non-nil, then QNAMES are expanded."
236 (nreverse xml))))))) 247 (nreverse xml)))))))
237 248
238(defun xml-maybe-do-ns (name default xml-ns) 249(defun xml-maybe-do-ns (name default xml-ns)
239 "Perform any namespace expansion. NAME is the name to perform the expansion on. 250 "Perform any namespace expansion.
251NAME is the name to perform the expansion on.
240DEFAULT is the default namespace. XML-NS is a cons of namespace 252DEFAULT is the default namespace. XML-NS is a cons of namespace
241names to uris. When namespace-aware parsing is off, then XML-NS 253names to uris. When namespace-aware parsing is off, then XML-NS
242is nil. 254is nil.
@@ -325,10 +337,8 @@ Returns one of:
325 (push (cons (cdar attr) (intern (concat ":" (cdr attr)))) 337 (push (cons (cdar attr) (intern (concat ":" (cdr attr))))
326 xml-ns)))) 338 xml-ns))))
327 339
328 ;; expand element names 340 (setq children (list attrs (xml-maybe-do-ns node-name "" xml-ns)))
329 (setq node-name (list (xml-maybe-do-ns node-name "" xml-ns)))
330 341
331 (setq children (list attrs node-name))
332 ;; is this an empty element ? 342 ;; is this an empty element ?
333 (if (looking-at "/>") 343 (if (looking-at "/>")
334 (progn 344 (progn
@@ -383,8 +393,8 @@ Returns one of:
383 (error "XML: Invalid character"))))) 393 (error "XML: Invalid character")))))
384 394
385(defun xml-parse-attlist (&optional xml-ns) 395(defun xml-parse-attlist (&optional xml-ns)
386 "Return the attribute-list after point. Leave point at the 396 "Return the attribute-list after point.
387first non-blank character after the tag." 397Leave point at the first non-blank character after the tag."
388 (let ((attlist ()) 398 (let ((attlist ())
389 end-pos name) 399 end-pos name)
390 (skip-syntax-forward " ") 400 (skip-syntax-forward " ")
@@ -575,7 +585,7 @@ This follows the rule [28] in the XML specifications."
575 585
576;; Fixme: Take declared entities from the DTD when they're available. 586;; Fixme: Take declared entities from the DTD when they're available.
577(defun xml-substitute-entity (match) 587(defun xml-substitute-entity (match)
578 "Subroutine of xml-substitute-special." 588 "Subroutine of `xml-substitute-special'."
579 (save-match-data 589 (save-match-data
580 (let ((match1 (match-string 1 str))) 590 (let ((match1 (match-string 1 str)))
581 (cond ((string= match1 "lt") "<") 591 (cond ((string= match1 "lt") "<")
@@ -612,9 +622,15 @@ This follows the rule [28] in the XML specifications."
612;;** 622;;**
613;;******************************************************************* 623;;*******************************************************************
614 624
615(defun xml-debug-print (xml) 625(defun xml-debug-print (xml &optional indent-string)
626 "Outputs the XML in the current buffer.
627XML can be a tree or a list of nodes.
628The first line is indented with the optional INDENT-STRING."
629 (setq indent-string (or indent-string ""))
616 (dolist (node xml) 630 (dolist (node xml)
617 (xml-debug-print-internal node ""))) 631 (xml-debug-print-internal node indent-string)))
632
633(defalias 'xml-print 'xml-debug-print)
618 634
619(defun xml-debug-print-internal (xml indent-string) 635(defun xml-debug-print-internal (xml indent-string)
620 "Outputs the XML tree in the current buffer. 636 "Outputs the XML tree in the current buffer.
@@ -629,24 +645,28 @@ The first line is indented with INDENT-STRING."
629 (insert ?\ (symbol-name (caar attlist)) "=\"" (cdar attlist) ?\") 645 (insert ?\ (symbol-name (caar attlist)) "=\"" (cdar attlist) ?\")
630 (setq attlist (cdr attlist))) 646 (setq attlist (cdr attlist)))
631 647
632 (insert ?>)
633
634 (setq tree (xml-node-children tree)) 648 (setq tree (xml-node-children tree))
635 649
636 ;; output the children 650 (if (null tree)
637 (dolist (node tree) 651 (insert ?/ ?>)
638 (cond 652 (insert ?>)
639 ((listp node) 653
640 (insert ?\n) 654 ;; output the children
641 (xml-debug-print-internal node (concat indent-string " "))) 655 (dolist (node tree)
642 ((stringp node) (insert node)) 656 (cond
643 (t 657 ((listp node)
644 (error "Invalid XML tree")))) 658 (insert ?\n)
645 659 (xml-debug-print-internal node (concat indent-string " ")))
646 (insert ?\n indent-string 660 ((stringp node) (insert node))
647 ?< ?/ (symbol-name (xml-node-name xml)) ?>))) 661 (t
662 (error "Invalid XML tree"))))
663
664 (when (not (and (null (cdr tree))
665 (stringp (car tree))))
666 (insert ?\n indent-string))
667 (insert ?< ?/ (symbol-name (xml-node-name xml)) ?>))))
648 668
649(provide 'xml) 669(provide 'xml)
650 670
651;;; arch-tag: 5864b283-5a68-4b59-a20d-36a72b353b9b 671;; arch-tag: 5864b283-5a68-4b59-a20d-36a72b353b9b
652;;; xml.el ends here 672;;; xml.el ends here