簡體   English   中英

在 Emacs 上漂亮地打印 XML 文件

[英]Pretty printing XML files on Emacs

我使用 emacs 來編輯我的 xml 文件(nxml-mode),並且由機器生成的文件沒有任何漂亮的標簽格式。

我已經搜索了漂亮的縮進打印整個文件並保存它,但無法找到一種自動方式。

有辦法嗎? 或者至少有一些 linux 上的編輯器可以做到這一點。

您甚至不需要編寫自己的函數 - sgml-mode(一個 gnu emacs 核心模塊)有一個名為 (sgml-pretty-print ...) 的內置漂亮打印函數,它接受區域開始和結束參數。

如果您正在剪切和粘貼 xml,並且發現您的終端在任意位置切線,您可以使用這款漂亮的打印機,它首先修復斷線。

如果您只需要漂亮的縮進而不引入任何新的換行符,您可以使用以下按鍵將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") (setq end (1+ end)))
    (indent-region begin end))
  (message "Ah, much better!"))

這不依賴於像 Tidy 這樣的外部工具。

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

"M-| xmllint --format -" 將格式化所選區域

"Cu M-| xmllint --format -" 會做同樣的事情,用輸出替換區域

當我想格式化和縮進 XML 或 HTML 時,我使用nXML 模式進行編輯和整理 Tidy還有一個 Emacs 接口。

用於引入換行符然后漂亮的打印

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

感謝上面的 Tim Helmstedt,我做了這樣的 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)))

快速簡便。 非常感謝。

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

  • search-forward-regexp沒有指定結束,所以它將對從區域開始到緩沖區結束(而不是區域結束)的內容進行操作
  • 正如 Cheeso 指出的那樣,現在增量正確end
  • 它會在<tag></tag>之間插入一個中斷,這會修改它的值。 是的,從技術上講,我們正在修改此處所有內容的值,但空的開始/結束更有可能是重要的。 現在使用兩個單獨的、稍微更嚴格的搜索來避免這種情況。

仍然有“不依賴外部整潔”等。但是, incf宏確實需要cl

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 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!"))

一種方法是如果您有以下格式的內容

<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>

在 VIM 中,您可以通過

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

希望這可以幫助。

我采用了Jason Viers 的版本並添加了邏輯以將 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. Emacs nxml-mode 可以處理呈現的格式,但您必須拆分行。
  2. 對於根本不值得的更長的文件。 對較長的文件運行此樣式表(最好與 Saxon 一起使用,恕我直言,行縮進是正確的)以獲得漂亮的打印效果。 對於您想要保留空白的任何元素,在“programlisting”旁邊添加它們的名稱,如“programlisting yourElementName”

HTH

Tidy 看起來是一個不錯的模式。 必須看看它。 如果我真的需要它提供的所有功能,我會使用它。

無論如何,這個問題困擾了我大約一個星期,我沒有正確搜索。 發帖后,我開始搜索並找到一個帶有elisp功能的網站,它做得很好。 作者還建議使用 Tidy。

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

很快就會在我的博客上發布它。 這是一篇關於它帖子(帶有到 Marcel 網站的鏈接)。

我使用xml-reformat-tags -parse.el 中的xml-reformat-tags 通常你會希望在運行這個命令時在文件的開頭有一個點。

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

我還附上了我的代碼來啟動 xml-parse。 不確定這是否是最好的 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))
)

如果您使用spacemacs ,只需使用命令“spacemacs/indent-region-or-buffer”。

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

截至 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))))

然后只需調用Mx reformat-xml

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM