emacsを使用してxmlファイルを編集し(nxml-mode)、ファイルはマシンによって生成されたもので、タグの適切なフォーマットがありません。
インデントを付けてファイル全体をきれいに印刷して保存することを検索しましたが、自動的な方法を見つけることができませんでした。
方法はありますか?または、それを実行できるLinux上の少なくともいくつかのエディター。
回答:
独自の関数を作成する必要はありません。sgml-mode(gnu emacsコアモジュール)には、領域の開始引数と終了引数を受け取る(sgml-pretty-print ...)という組み込みのプリティプリント関数があります。
xmlを切り取って貼り付けていて、端末が任意の場所で行を切り刻んでいることがわかった場合は、最初に破線を修正するこのプリティプリンターを使用できます。
sgml-mode
時間の経過とともにどのように変化したのかわかりません。今日、私は呼び出されC-x C-f foo.xml
、M-x sgml-mode
そして、M-x sgml-pretty-print
そして私のxmlファイルはかなり印刷してしまいました。(まあ、emacsは完了する前に20秒以上
C-x g
バッファ全体をリージョンとして選択する必要もありました。
C-x h
、その後とM-x sgml-pretty-print
。xmlは今ではきれいにフォーマットされています
改行を導入せずにかなりのインデントが必要な場合は、indent-region
次のキーストロークを使用してコマンドをバッファ全体に適用できます。
C-x h
C-M-\
改行も導入する必要があり、開始タグと終了タグが別々の行にある場合は、BenjaminFerrariによって作成された次の非常に優れたelisp関数を使用できます。私は彼のブログでそれを見つけました、そして私がここでそれを複製することが大丈夫であることを願っています:
(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-"は同じことを行い、領域を出力に置き換えます
上記のTimHelmstedtのおかげで、私は次のように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)))
速くて簡単。どうもありがとう。
(indent-region 0 (count-lines (point-min) (point-max)))
改行を導入してからプリティプリントする場合
M-x sgml-mode
M-x sgml-pretty-print
ベンジャミンフェラーリのバージョンに加えたいくつかの調整は次のとおりです。
search-forward-regexp
終了を指定しなかったので、(領域の終わりではなく)領域の最初からバッファの終わりまでのものを操作しますend
Cheesoが指摘したように、適切にインクリメントするようになりました。<tag></tag>
に区切りを挿入し、その値を変更します。はい、技術的にはここですべての値を変更していますが、空の開始/終了が重要になる可能性がはるかに高くなります。これを回避するために、2つの別々の少し厳密な検索を使用するようになりました。まだ「外部整理に頼らない」などがありますcl
が、incf
マクロは必要です。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 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!"))
1つの方法は、以下の形式のものがある場合です。
<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=
お役に立てれば。
私が取ったジェイソン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!"))
xml-parse.elxml-reformat-tags
から使用しますます。通常、このコマンドを実行するときは、ファイルの先頭をポイントにする必要があります。
ファイルがEmacspeakに組み込まれているのは興味深いことです。Emacspeakを毎日使っていたとき、私は思ったxml-reformat-tags
はEmacsが組み込まれている。ある日、私はそれを失い、それをインターネットで検索しなければならなかったので、上記のwikiページに入りました。
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))
)
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/
私はベンジャミンフェラーリバージョンの方がずっと好きだと思います。内部プリティプリントは常に終了タグを値の後の新しい行に配置し、タグ値に不要なCRを挿入します。
wrong type argument: stringp, nil