2008-08-15 39 views
73

我使用emacs編輯我的xml文件(nxml-mode),並且由機器生成的文件沒有任何漂亮的標籤格式。在Emacs上打印漂亮的XML文件

...我已經尋找漂亮的印刷與縮進整個文件並將其保存,但無法找到一個自動的方式。

有沒有辦法?或者至少可以做一些Linux編輯器。

回答

23

我用nXML mode編輯和Tidy時,我想格式化和縮進XML或HTML。還有an Emacs interface to Tidy.

+0

2013年底tidy.el版本:20111222.1756無法在Emacs 24上使用錯誤的類型參數運行:stringp,nil``` – keiw 2013-12-21 12:38:16

+0

@keiw這可能是因爲你在沒有文件名的緩衝區中執行它。至少有同樣的錯誤並將其追溯到我的身邊。 – Alf 2014-01-21 13:10:02

1

整潔看起來像一個很好的模式。必須看看它。如果我真的需要它提供的所有功能,請使用它。

反正這個問題我困擾了大約一個星期,我並沒有正確地搜索。張貼後,我開始搜索並找到一個網站,其中有一個elisp function,這很不錯。作者還建議使用Tidy。

感謝您的回答Marcel (太糟糕了,我沒有足夠的積分來升級你)

近期將發佈關於它在我的博客。 這是一個post about it(連接到Marcel的網站)。

2
  1. Emacs nxml-mode可以使用呈現的格式,但您必須拆分這些行。
  2. 對於更長的文件,根本不值得。運行這個樣式表(理想情況下與薩克森 哪些恕我直言獲得行縮進約右)對較長的文件 得到一個漂亮的漂亮打印。對於要保留空白的任何元素 添加自己的名字旁邊 'programlisting' 作爲 'programlisting yourElementName'

HTH

85

如果你只需要在不引入任何新的換行符漂亮縮進,您可以將indent-region命令將整個緩衝區與這些按鍵:

C-x h 
C-M-\ 

如果您還需要引入換行符,所以打開和關閉標籤是分開的,你可以使用以下非常好的elisp函數,編寫Benjamin Ferrari。我在他的博客上發現了它,並希望我可以在此重現它:

(defun bf-pretty-print-xml-region (begin end) 
    "Pretty format XML markup in region. You need to have nxml-mode 
http://www.emacswiki.org/cgi-bin/wiki/NxmlMode installed to do 
this. The function inserts linebreaks to separate tags that have 
nothing but whitespace between them. It then indents the markup 
by using nxml's indentation rules." 
    (interactive "r") 
    (save-excursion 
     (nxml-mode) 
     (goto-char begin) 
     (while (search-forward-regexp "\>[ \\t]*\<" nil t) 
     (backward-char) (insert "\n")) 
     (indent-region begin end)) 
    (message "Ah, much better!")) 

這不依賴於外部工具,如Tidy。

+1

好的defun,謝謝。從上面的漂亮的defun中刪除(nxml-mode)允許它以內置於emacs 22.2.1的sgml模式工作。但我修改它來完成整個緩衝區(point-min)到(point-max),因爲那是我的主要事情。另外,還有一個錯誤:對於您插入的每一個換行符,您都需要增加結尾。 – Cheeso 2009-06-03 15:33:44

+0

如何在Emacs中使用此功能?我已經將函數代碼複製並粘貼到* scratch *緩衝區中並進行了評估。現在,我該如何調用這個函數? – 2011-02-21 12:01:34

+1

評估defun之後,可以像調用其他任何函數一樣調用它:M-x bf-pretty-print-xml-region。 (當然,你不需要輸入全部,當然,使用Tab完成:Mx bf 就足夠了。)你可能不想每次使用它時都定義這個函數,所以把它放在某個地方在啓動時加載,例如在〜/ .emacs.d/init.el – 2011-02-22 16:50:50

93

你甚至都不需要編寫自己的函數 - SGML的模式(GNU Emacs的核心模塊)有一個內置的叫(SGML的漂亮打印漂亮的打印功能...)它需要區域開始和結束參數。

如果您正在剪切並粘貼xml,並且您發現您的終端正在任意位置切斷線條,則可以使用此首先修復虛線的pretty printer

0

我怕我喜歡本傑明法拉利版本好多了。內部漂亮的打印總是將結束標記放在值後面的新行中,在標記值中插入不需要的CR。

33

Emacs可以使用M- |運行任意命令。如果您已經安裝xmllint:

「M- | xmllint --format - 」 將格式化選定區域

「銅M- | xmllint --format - 」 會做同樣的,隨着替換區域輸出

17

感謝Tim黑爾姆施泰特上面我做ST這樣的:

(defun nxml-pretty-format() 
    (interactive) 
    (save-excursion 
     (shell-command-on-region (point-min) (point-max) "xmllint --format -" (buffer-name) t) 
     (nxml-mode) 
     (indent-region begin end))) 

快速和容易。非常感謝。

7

這裏是我本傑明法拉利的版本做了一些調整:

  • search-forward-regexp沒有指定一個結束,所以它會在東西運營從區域的開始到緩衝區(而不是區域月底結束)
  • 正如Cheeso指出的那樣,現在正確地增加end
  • 它會在<tag></tag>之間插入一箇中斷,這會修改其值。是的,從技術上講,我們正在修改一切的價值,但空的開始/結束更有可能是重要的。現在使用兩個單獨的,稍微嚴格的搜索來避免這種情況。

仍然有「不依靠外部整潔」,等等。但是,它確實需要clincf宏。這樣做的

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
;; pretty print xml region 
(defun pretty-print-xml-region (begin end) 
    "Pretty format XML markup in region. You need to have nxml-mode 
http://www.emacswiki.org/cgi-bin/wiki/NxmlMode installed to do 
this. The function inserts linebreaks to separate tags that have 
nothing but whitespace between them. It then indents the markup 
by using nxml's indentation rules." 
    (interactive "r") 
    (save-excursion 
    (nxml-mode) 
    (goto-char begin) 
    ;; split <foo><foo> or </foo><foo>, but not <foo></foo> 
    (while (search-forward-regexp ">[ \t]*<[^/]" end t) 
     (backward-char 2) (insert "\n") (incf end)) 
    ;; split <foo/></foo> and </foo></foo> 
    (goto-char begin) 
    (while (search-forward-regexp "<.*?/.*?>[ \t]*<" end t) 
     (backward-char) (insert "\n") (incf end)) 
    (indent-region begin end nil) 
    (normal-mode)) 
    (message "All indented!")) 
5

一種方法是 如果你有一些在下面的格式

<abc>  <abc><abc> <abc></abc> </abc></abc>  </abc> 

在Emacs,會

M-x nxml-mode 
M-x replace-regexp RET > *<RET>C-q C-j< RET 
C-M-\ to indent 

這將縮進上面的XML例子下面

<abc> 
    <abc> 
    <abc> 
     <abc> 
     </abc> 
    </abc> 
    </abc> 
</abc> 

在VI中M你可以做到這一點

:set ft=xml 
:%s/>\s*</>\r</g 
ggVG= 

希望這會有所幫助。

2

我花了Jason Viers' version並添加了邏輯來將xmlns聲明放在他們自己的行上。這假定你有xmlns =和xmlns:沒有中間空格。

(defun cheeso-pretty-print-xml-region (begin end) 
    "Pretty format XML markup in region. You need to have nxml-mode 
http://www.emacswiki.org/cgi-bin/wiki/NxmlMode installed to do 
this. The function inserts linebreaks to separate tags that have 
nothing but whitespace between them. It then indents the markup 
by using nxml's indentation rules." 
    (interactive "r") 
    (save-excursion 
    (nxml-mode) 
    ;; split <foo><bar> or </foo><bar>, but not <foo></foo> 
    (goto-char begin) 
    (while (search-forward-regexp ">[ \t]*<[^/]" end t) 
     (backward-char 2) (insert "\n") (incf end)) 
    ;; split <foo/></foo> and </foo></foo> 
    (goto-char begin) 
    (while (search-forward-regexp "<.*?/.*?>[ \t]*<" end t) 
     (backward-char) (insert "\n") (incf end)) 
    ;; put xml namespace decls on newline 
    (goto-char begin) 
    (while (search-forward-regexp "\\(<\\([a-zA-Z][-:A-Za-z0-9]*\\)\\|['\"]\\) \\(xmlns[=:]\\)" end t) 
     (goto-char (match-end 0)) 
     (backward-char 6) (insert "\n") (incf end)) 
    (indent-region begin end nil) 
    (normal-mode)) 
    (message "All indented!")) 
1

我用xml-reformat-tagsxml-parse.el。通常,在運行此命令時,您需要在文件的開頭有點。

有趣的是,該文件被合併到Emacspeak。當我每天使用Emacspeak時,我認爲xml-reformat-tags是Emacs內置的。有一天,我失去了它,不得不進行互聯網搜索,因此進入了上面提到的維基頁面。

我也附上我的代碼來啓動xml解析。不知道這是否是最好的Emacs代碼,但似乎適用於我。

(if (file-exists-p "~/.emacs.d/packages/xml-parse.el") 
    (let ((load-path load-path)) 
    (add-to-list 'load-path "~/.emacs.d/packages") 
    (require 'xml-parse)) 
) 
11

對於引入換行符,然後打印漂亮

M-x sgml-mode 
M-x sgml-pretty-print 
1

如果使用spacemacs,只需使用命令「spacemacs /縮進區域或緩衝」。

M-x spacemacs/indent-region-or-buffer 
0

2017年的emacs已經自帶這個功能默認,但你有這個小功能寫入到您的~/.emacs.d/init.el

(require 'sgml-mode) 

(defun reformat-xml() 
    (interactive) 
    (save-excursion 
    (sgml-pretty-print (point-min) (point-max)) 
    (indent-region (point-min) (point-max)))) 

然後就叫M-x reformat-xml

來源:https://davidcapello.com/blog/emacs/reformat-xml-on-emacs/