Destul de imprimat fișiere XML pe Emacs

Eu folosesc emacs pentru a edita fișierele xml (nxml-mode) și fișierele au fost generate de mașină nu au nici o formatare destul de etichete.

Am căutat destulă imprimare întregului fișier cu indentare și salvând-o, dar nu a reușit să găsească o cale automată.

Există o cale? Sau atleast un editor pe linux care o poate face.

0
fr hi bn

14 răspunsuri

I use nXML mode for editing and Tidy when I want to format and indent xml or HTML. There is also an Emacs interface to Tidy.

0
adăugat
Până la sfârșitul anului 2013 tidy.el Versiunea: 20111222.1756 nu reușește să ruleze pe Emacs 24 cu argument greșit de tip: stringp, nil
adăugat autor keiw, sursa
@keiw Asta probabil pentru că o faci într-un tampon care nu are un nume de fișier. A apărut aceeași eroare și am urmărit-o cel puțin pe partea mea.
adăugat autor Alf, sursa

Am luat versiunea lui Jason Viers și am adăugat o logică pentru a plasa declarații xmlns pe propriile linii. Aceasta presupune că aveți xmlns = și xmlns: fără spații libere intermediare.

(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  or , but not 
    (goto-char begin)
    (while (search-forward-regexp ">[ \t]*<[^/]" end t)
      (backward-char 2) (insert "\n") (incf end))
    ;; split  and 
    (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!"))
0
adăugat

Tidy arată ca un mod bun. Trebuie să se uite la el. Îl voi folosi dacă am nevoie de toate caracteristicile pe care le oferă.

Oricum, această problemă mă deranja timp de o săptămână și nu căutam cum trebuie. După ce am postat, am început să caut și să găsesc un site cu un funcția elisp care o face destul de bine. Autorul sugerează, de asemenea, utilizarea Tidy.

Vă mulțumim pentru răspunsul lui Marcel (prea rău că nu am suficiente puncte pentru a vă ajuta) .

Will post about it soon on my blog. Here is a post about it (with a link to Marcel's site).

0
adăugat

Pentru introducerea rupturilor de linie și apoi pentru imprimarea destulă

M-x sgml-mode
M-x sgml-pretty-print
0
adăugat

Eu folosesc de la xml-parse.el . De obicei, veți dori să aveți punctul la începutul fișierului când executați această comandă.

Este interesant faptul că fișierul este încorporat în Emacspeak . Când am folosit Emacspeak zilnic, m-am gândit că xml-reformat-tags este un Emacs încorporat. Într-o zi l-am pierdut și a trebuit să fac o căutare pe internet pentru asta, și astfel am intrat pe pagina wiki menționată mai sus.

Am atașat și codul meu pentru a începe xml-parse. Nu sunt sigur dacă aceasta este cea mai bună bucată din codul Emacs, dar pare să funcționeze pentru mine.

(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))
)
0
adăugat

iată câteva modificări pe care le-am făcut versiunii lui Benjamin Ferrari:

  • search-forward-regexp nu specifica un sfarsit, asa ca va functiona pe chestii de la inceputul regiunii la sfarsitul bufferului (in loc de sfarsitul regiunii)
  • Acum incrementează end corect, așa cum a observat Cheeso.
  • ar introduce o pauză între , care modifică valoarea sa. Da, din punct de vedere tehnic, modificăm valorile de aici, dar un început/sfârșit gol este mult mai probabil să fie semnificativ. Acum utilizează două căutări separate, puțin mai stricte, pentru a evita acest lucru.

Totuși, aceasta nu are nevoie de cl pentru macrocomanda 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  or , but not 
    (while (search-forward-regexp ">[ \t]*<[^/]" end t)
      (backward-char 2) (insert "\n") (incf end))
    ;; split  and 
    (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!"))
0
adăugat

Dacă aveți nevoie doar de indentare fără introducerea unor noi linii de rupere, puteți aplica comanda indent-region la întregul buffer cu următoarele apăsări de taste:

C-x h
C-M-\

Dacă trebuie, de asemenea, să introduceți linii de rupere, astfel încât etichetele de deschidere și închidere să fie pe linii separate, puteți utiliza următoarea funcție foarte frumoasă, scrisă de Benjamin Ferrari . Am gasit-o pe blogul sau si sper ca este bine sa o reproduc aici:

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

Acest lucru nu se bazează pe un instrument extern cum ar fi Tidy.

0
adăugat
Bună defuncție, mulțumesc. Eliminarea modului (nxml-mode) de la defun-ul de imprimare destul de mare de mai sus îi permite să lucreze în modul sgml care este încorporat în emacs 22.2.1. Dar am modificat-o pentru a face întregul tampon (point-min) la (point-max), pentru că acesta este principalul meu lucru. De asemenea, o eroare: pentru fiecare linie nouă pe care o introduceți, va trebui să măriți sfârșitul.
adăugat autor Cheeso, sursa
adăugat autor Cheeso, sursa
Cum despre ruperea listelor de atribute lungi?
adăugat autor ceving, sursa
După evaluarea defunerii, o puteți invoca ca orice altă funcție: M-x bf-pretty-print-xml-region. (Nu trebuie să tastați toate, desigur, utilizați completarea fila: Mx bf ar trebui să fie de ajuns.) Probabil că nu doriți să definiți funcția de fiecare dată când doriți să o utilizați, așa că puneți-o undeva în cazul în care este încărcat la start-time, de exemplu în ~/.emacs.d/init.el
adăugat autor Christian Berg, sursa
Cum pot utiliza această funcție în Emacs? Am copiat și lipit codul funcției în tampon zero și l-am evaluat. Acum, cum pot invoca această funcție?
adăugat autor Alexandre Rademaker, sursa
Acest lucru este fabulos, deoarece îngrijorat se plânge de encodings de caractere invalide și dorește să le curăț înainte ca acesta să reformuleze fișierul! Uneori, punctul este de a vedea structura unui fișier xml rupt și ordonată va refuza să ajute.
adăugat autor TauPan, sursa
  1. Emacs nxml-mode poate funcționa în formatul prezentat, dar va trebui să împărțiți liniile.
  2. Pentru fișiere mai lungi, care pur și simplu nu merită. Rulați această foaie de stil (în mod ideal cu Saxon care IMHO devine linia liniare dreapta) împotriva fișierelor mai lungi pentru a obține o imprimare frumoasă frumoasă. Pentru orice elemente în care doriți să păstrați spațiu alb adăugați numele lor alături de "listarea programelor" ca în "listarea programelor dvs.ElementName"

HTH

0
adăugat

Nu aveți nevoie nici măcar să vă scrieți propria funcție - sgml-mode (un modul de bază gnu emacs) are o funcție de tipărire drăguță, numită (sgml-pretty-print ...), care ia argumentele de început și de sfârșit ale regiunii.

Dacă tăiați și lipiți xml și găsiți că terminalul taie liniile în locații arbitrare, puteți folosi acest destul de imprimanta care fixează mai întâi linii întrerupte.

0
adăugat
Nu sunt sigur cum s-ar putea să se fi schimbat sgml-mode în timp. Astăzi am invocat Cx Cf foo.xml , Mx sgml-mode , apoi Mx sgml-pretty-print . (Ei bine, emacs a spânzurat timp de douăzeci de secunde sau mai mult înainte de a termina. A fost un fișier cu o singură linie înainte de imprimarea destulă și 720 de linii după).
adăugat autor daveloyall, sursa
De fapt, de asemenea, a trebuit să fac C-x g pentru a selecta întregul buffer ca regiune.
adăugat autor daveloyall, sursa
Cum pot executa o funcție care trece regiunea ca argument?
adăugat autor Alexandre Rademaker, sursa
(sgml-pretty-print (începutul regiunii) (sfârșitul regiunii))
adăugat autor ScootyPuff, sursa

Emacs poate executa comenzi arbitrare cu M- |. Dacă ați instalat xmllint:

"M- | xmllint --format -" va forma regiunea selectată

"C-u M-xmllint -format-" va face același lucru, înlocuind regiunea cu ieșirea

0
adăugat
Utilizați M-x mark-whole-buffer în față pentru a marca întregul conținut tampon ca regiune de procesat.
adăugat autor Harald, sursa
@bubak de mai jos scrise acest lucru. Mulțumiri!
adăugat autor Tim Helmstedt, sursa

Mulțumită lui Tim Helmstedt de mai sus am făcut-o în felul următor:

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

rapid și ușor. Mulţumesc mult.

0
adăugat
Acest lucru mi-a dat o eroare la GNU Emacs 24, așa că am schimbat ultima linie la: (indent-region 0 (numărătoare de linii (punct-min) (punct-max)))
adăugat autor John J. Camilleri, sursa

O modalitate de a face este Dacă aveți ceva în formatul de mai jos

                

În Emacs, încercați

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

Acesta va fi indentat deasupra exemplului xml de mai jos


  
    
      
      
    
  

În VIM puteți face acest lucru prin

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

Sper că acest lucru vă ajută.

0
adăugat

Dacă utilizați spacemacs , folosiți comanda 'spacemacs/indent-region-or-buffer'.

M-x spacemacs/indent-region-or-buffer
0
adăugat

din 2017 emacs deja vine cu această capacitate în mod implicit, dar trebuie să scrieți această mică funcție în ~/.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))))

then just call M-x reformat-xml

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

0
adăugat