nxml-mode is the default major mode for editing XML, although emacs still includes its prior implementation, called xmlMode.
’Note’ the colorization (font-lock) won’t work if you change the emacs colors.
An internal variable named rng-schema-locating-files tells NxmlMode all the places to search for schemas. This variable’s default value is (’schemas.xml’, ‘DIST-DIR/schema/schemas.xml’), where DIST-DIR is the distribution directory where nxml is installed.
To download schemas, visit NxmlModeSchemas.
if you would like to edit html files in nxml-mode:
(fset 'html-mode 'nxml-mode)
If you have xml files for which the first element is html, you end up in html mode instead of nxml mode. This is because of the default magic-mode-alist.
I don’t know how to write elisp to remove html-mode from magic-mode-alist, but
(fset 'html-mode 'nxml-mode)
does the job. This works if you never edit html in emacs with anything other than nxml-mode. – DougRansom
;;; Use nxml-mode instead of sgml, xml or html mode. (mapc (lambda (pair) (if (or (eq (cdr pair) 'xml-mode) (eq (cdr pair) 'sgml-mode) (eq (cdr pair) 'html-mode)) (setcdr pair 'nxml-mode))) magic-mode-alist)
works for me. – TrentBuck
For me magic-mode-alist is nil, but using auto-mode-alist instead of magic-mode-alist in the above works. – StephenPowell
Being an XML newbie, I had been creating documents without the beginning “<
After mending my ways, I was surprised to find myself in
‘xml-mode’ instead of nxml.
After fighting with this for a while I found the
‘set-auto-mode’ function in file.el.
‘set-auto-mode’ is essentially a hairier (but more careful) version of the
‘hack-local-variables-hook’ code shown below.
‘set-auto-mode’ doesn’t respect
‘auto-mode-alist’ unless the mode is mentioned in
So, to make
‘set-auto-mode’ respect ‘auto-mode-alist’, say:
(setq xml-based-modes (cons 'nxml-mode xml-based-modes))
But some xml files are not named nicely. To also force
‘nxml-mode’ for all documents with contents beginning
"<\\?xml \\|<!DOCTYPE" say:
(fset 'xml-mode 'nxml-mode)
An alternative method is to search for an XML prolog at the beginning of the file:
(add-hook 'hack-local-variables-hook (lambda () (save-excursion (when (search-forward-regexp "^<\\?xml" 6 0) (nxml-mode) ))))
That is very cool, and it works. This alternative method was marked deprecated, but there’s some dispute over this.
The sniplet above does not work with
‘M-x normal-mode’. You get “invalid search bound”, “wrong side of point” errors. Moving the point to the beginning of the buffer actually helps:
(add-hook 'hack-local-variables-hook (lambda () (save-excursion (goto-char (point-min)) (when (search-forward-regexp "^<\\?xml" 6 0) (nxml-mode) ))))
There is a simple solution for this. You can customize
‘magic-mode-alist’, which holds the patterns for
(setq magic-mode-alist (cons '("<\\?xml " . nxml-mode) magic-mode-alist))
Brining it altogether into a elisp fragment that works, define a variable site-lisp-path to where nxml-mode is and:
;path to where nxml is (set 'nxml-path (concat site-lisp-path "nxml-mode/")) (load (concat nxml-path "rng-auto.el")) (add-to-list 'auto-mode-alist (cons (concat "\\." (regexp-opt '("xml" "xsd" "sch" "rng" "xslt" "svg" "rss") t) "\\'") 'nxml-mode)) (unify-8859-on-decoding-mode) (setq magic-mode-alist (cons '("<＼＼?xml " . nxml-mode) magic-mode-alist)) (fset 'xml-mode 'nxml-mode)
(fset 'html-mode 'nxml-mode)
if you would like to edit html files in nxml-mode.
To avoid some of the problem with major mode above you can replace all occurences of xml-mode in auto-mode-alist and magic-mode-alist. I found this to be a bit of a problem so I wrote fmode.el. This changes auto-mode-alist and magic-mode-alist in a simple way. It is available as a part of NxhtmlMode.
Oliver Steele’s nxml-mode additions adds functions to revert and edit the current schema. This is useful if you are developing schema (*.rnc) files concurrently with the XML files, or using nxml-mode to preview the schema validation.
On firstname.lastname@example.org mailing list Paul Brown wrote about rnc-mode: I have been using rnc-mode (see http://www.pantor.com/download.html) to edit the (.rnc) files (highlighting, mostly) and the nxml-mode to load and validate the RNC.
If you want to edit XML fragments and still use the validation in nxml-mode you can try NxhtmlMode. This is used for example when editing PHP. The framework for this is general, but it requires a bit elisp skill to use it for fragment of other XML DTDs than XHTML.
‘icicle-search-xml-element’– search elements whose names match a regexp
‘sexp’– when in
‘nxml-sexp-element-flag’controls what sexp means – set it to
‘t’if you want whole elements as sexps.
You can use `
C-M-;’ in the minibuffer to toggle whether commented text is to be ignored (i.e., don’t bother with sexps in comments.
Switch to XmlMode and use the tools menu.
Spelling is not a problem anymore: to use flyspell, add the following to your .emacs:
(add-to-list 'flyspell-prog-text-faces 'nxml-text-face)
…and use flyspell-prog-mode, not flyspell-mode.
I’m getting the following backtrace when opening any nxml-mode file:
Debugger entered--Lisp error: (error "Variable binding depth exceeds max-specpdl-size") (let* ((open-group ...) (close-group ...) (open-charset ...) (close-charset ...)) (cond (... ...) (... ...) (... ...) (t ...))) regexp-opt-group(nil t t) (concat open-charset (regexp-opt-group (cdr strings) t t) "?" close-charset) (cond ((= ... 1) (if ... ... ...)) ((= ... 0) (concat open-charset ... "?" close-charset)) ((= ... ...) (concat open-charset ... close-charset)) (t (let ... ...))) (let* ((open-group ...) (close-group ...) (open-charset ...) (close-charset ...)) (cond (... ...) (... ...) (... ...) (t ...))) regexp-opt-group(nil t t)
(and so on). File opens successfully on second attempt, but you have to manually enter nxml-mode.
Anyone else had these problems? Previous release works fine.
I’m having the same problem.
I’d like to be able to see the current XML path in the modeline in addition to or in place of the line number. For example, editing an XHTML doc it might say “/html/body/p/b”. Please someone say there’s an easy way to do this! It would make editing big XML files so much easier.
I have included nxml-where.el in NxhtmlMode. Please grab it there.
Here is a simple function to show the current path in the echo area:
(defun nxml-where () "Display the hierarchy of XML elements the point is on as a path." (interactive) (let ((path nil)) (save-excursion (save-restriction (widen) (while (and (< (point-min) (point)) ;; Doesn't error if point is at beginning of buffer (condition-case nil (progn (nxml-backward-up-element) ; always returns nil t) (error nil))) (setq path (cons (xmltok-start-tag-local-name) path))) (if (called-interactively-p t) (message "/%s" (mapconcat 'identity path "/")) (format "/%s" (mapconcat 'identity path "/")))))))
Barely tested, improvements welcome. – EmilioLopes
You can use which-func-mode to show this info in the modeline, you just have to use (add-hook ‘which-func-functions ‘nxml-where) to tie the two together. – ZoltanIvanfi
Breaks if there is text that looks like start of a element in a comment, e.g. `<!– <example’ – MiserableVariable
Labels and inputs in forms are incorrectly flagged as invalid. In this valid sample document, the label and input will be considered errors:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title></title></head> <body> <form action="" method="get"> <label for="inputname">Label for field: </label> <input type="text" name="inputname" id="inputname" /> </form> </body> </html>
This is an error in nxml-mode, which doesn’t have a schema to validate XHTML Transitional. It can be fixed with a custom schema. The workaround is documented at http://tech.groups.yahoo.com/group/emacs-nxml-mode/message/1887
nXML mode already tries to correctlt comment comments, but sadly still fails:
<!-- foo -->
<!-- <\!-- foo -\-> -->
which still has an invalid “--” inside, it would be better to create
<!-- <\!-\- foo -\-> -->
That is not an error in nXML, but in GNU Emacs proper (newcomment.el, to be exact). Nested comments are mangled by inserting the
\ character after the first character of the comment string, so
<\!--, as you said. However, in XML comments, the string
-- may not appear. The correct way to nest comments in XML would be to change it to
<!-\-. This is also broken in GNU Emacs 24 (last time I checked was early October 2011). I have written Lisp:mz-comment-fix.el to fix the problem.
Thanks for the ideas about escaping comments I hacked together a couple functions that work for me. Feedback welcomed. I was too lazy to properly integrate the functions into nXML mode. Thus the my- prefix on the functions.
(defun my-nxml-comment-region () "comment a block if in nXML mode; else call comment-region" (interactive) ;; KLUDGE: should bind key in buffer, but I'm lazy (cond ((string-equal mode-name "nXML") (save-excursion (narrow-to-region (point) (mark)) (goto-point-min) (save-excursion (replace-string "--" "\\-\\-")) (insert "<!--\n") (goto-point-max) (insert "-->\n") (widen))) (t (comment-region (point) (mark))))) (defun my-nxml-uncomment-region () "uncomment a block if in nXML mode; else call uncomment-region assumes it was commented by my-nxml-comment-region" (interactive) ;; KLUDGE: should bind key in buffer, but I'm lazy (cond ((string-equal mode-name "nXML") (save-excursion (search-backward "<!--\n") (delete-char 5) (let ((start (point)) end) (search-forward "-->\n") (delete-char -4) (setq end (point)) (save-excursion (replace-string "\\-\\-" "--" nil start end))))) (t (uncomment-region (point) (mark)))))