85

私は emacs を使用して xml ファイル (nxml-mode) を編集していますが、ファイルはマシンによって生成されたもので、タグの書式設定が適切ではありません。

ファイル全体をインデント付きできれいに印刷して保存する方法を検索しましたが、自動の方法を見つけることができませんでした。

方法はありますか?または、少なくともそれを実行できるLinux上のエディター。

4

15 に答える 15

113

独自の関数を記述する必要さえありません。sgml-mode (gnu emacs コア モジュール) には、(sgml-pretty-print ...) と呼ばれる組み込みのきれいな印刷関数があり、領域の開始と終了の引数を取ります。

xml をカット アンド ペーストしているときに、端末が任意の場所で行を切り刻んでいることに気付いた場合は、まず壊れた行を修正するこのきれいなプリンターを使用できます。

于 2009-02-27T16:47:05.117 に答える
89

改行を導入せずにかなりインデントする必要がある場合は、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のような外部ツールに依存していません。

于 2009-02-20T15:41:39.950 に答える
35

Emacs は M-| で任意のコマンドを実行できます。xmllint がインストールされている場合:

「M-| xmllint --format -」は、選択した領域をフォーマットします

「Cu M-| xmllint --format -」は同じことを行い、領域を出力に置き換えます

于 2010-02-02T03:50:04.800 に答える
25

編集にはnXML モードを使用し、XML や HTML をフォーマットしてインデントしたい場合はTidyを使用します。Tidy への Emacs インターフェイスもあります。

于 2008-08-15T17:47:29.893 に答える
20

上記の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)))

速くて簡単。どうもありがとう。

于 2010-11-25T21:00:50.373 に答える
20

改行を導入してきれいに印刷する場合

M-x sgml-mode
M-x sgml-pretty-print
于 2016-05-31T07:52:00.807 に答える
8

ベンジャミン・フェラーリのバージョンに私が加えたいくつかの微調整があります:

  • search-forward-regexp終了を指定しなかったため、領域の開始からバッファの終了まで (領域の終了ではなく) 処理を行います。
  • endCheeso が指摘したように、適切にインクリメントするようになりました。
  • の間にブレークを挿入し、<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!"))
于 2011-03-04T19:19:28.820 に答える
5

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=

お役に立てれば。

于 2011-11-04T02:32:33.367 に答える
2

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!"))
于 2013-01-29T18:21:56.437 に答える
2
  1. Emacs nxml-mode は提示された形式で動作しますが、行を分割する必要があります。
  2. それだけの価値のない長いファイルの場合。このスタイルシート (理想的には、私見が行のインデントをほぼ正しく取得する Saxon で) を長いファイルに対して実行して、見栄えの良い印刷を取得します。空白を保持したい要素については、「programlisting yourElementName」のように「programlisting」の横に名前を追加します。

HTH

于 2008-09-12T08:14:40.567 に答える
1

整頓は良いモードのように見えます。それを見なければなりません。それが提供するすべての機能が本当に必要な場合に使用します。

とにかく、この問題は私を約1週間悩ませていました、そして私はきちんと検索していませんでした。投稿した後、私は検索を開始し、それをかなりうまく行うelisp関数を備えた1つのサイトを見つけました。著者はまた、Tidyの使用を提案しています。

答えてくれてありがとうMarcel (残念ながら私はあなたをアップモッドするのに十分なポイントがありません)

すぐに私のブログに投稿します。これについての投稿があります(Marcelのサイトへのリンク付き)。

于 2008-08-15T18:09:10.227 に答える
1

spacemacsを使用する場合は、コマンド 'spacemacs/indent-region-or-buffer' を使用してください。

M-x spacemacs/indent-region-or-buffer
于 2016-08-10T08:33:32.453 に答える
1

私は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))
)
于 2014-02-02T14:35:39.653 に答える
0

残念ながら、ベンジャミン・フェラーリのバージョンの方がずっと好きです。内部のプリティ プリントでは、常に値の後に終了タグが新しい行に配置され、タグ値に不要な CR が挿入されます。

于 2009-05-12T18:18:21.687 に答える