Pregunta

Yo uso emacs para editar mis archivos xml (nxml-mode) y los archivos fueron generados por la máquina no tienen bastante formato de las etiquetas.

He buscado bastante la impresión de que todo el archivo con la sangría y el ahorro, pero no fue capaz de encontrar una manera automática.

Hay una manera?O al menos algún editor de linux que puede hacerlo.

¿Fue útil?

Solución

Yo uso nXML modo para la edición y Ordenado cuando quiero formatear y guión de HTML o XML.También hay una Emacs interfaz Ordenada.

Otros consejos

Usted incluso no necesita escribir su propia función - sgml-modo (gnu emacs módulo principal) tiene un built-in bastante función de impresión de llamada (sgml-pretty-print ...) que lleva a la región de comienzo y final de los argumentos.

Si usted está cortando y pegando xml y encontrará que el terminal es picar las líneas arbitrarias de lugares que usted puede utilizar este bastante impresora que corrige las líneas discontinuas en primer lugar.

Si sólo necesita bastante sangría sin la introducción de cualquier nuevo saltos de línea, se puede aplicar el indent-region comando para todo el búfer con estas combinaciones de teclas:

C-x h
C-M-\

Si usted también necesita introducir saltos de línea, por lo que la apertura y cierre de las etiquetas son en líneas separadas, puede utilizar el siguiente muy agradable elisp función, escrito por Benjamin Ferrari.Me lo encontré en su blog y espero que sea bien para mí reproducir aquí:

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

Esto no depende de una herramienta externa como Ordenado.

Emacs puede ejecutar comandos arbitrarios con M-|.Si usted tiene xmllint instalado:

"M-| xmllint --formato -" se dará formato a la región seleccionada

"C-u M-| xmllint --formato -" va a hacer lo mismo, en sustitución de la región con la salida de

Gracias a Tim Helmstedt arriba me hizo pt como este:

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

rápido y fácil.Muchas gracias.

Para introducir saltos de línea y, a continuación, bastante impresión

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

he aquí un par de cositas que he realizado para Benjamin Ferrari versión:

  • el search-forward-regexp no especifique un fin, por lo que podría operar en la materia, desde el comienzo de la región a fin de búfer (en lugar de la final de la región)
  • Ahora incrementos de end correctamente, como Cheeso señaló.
  • sería insertar una pausa entre <tag></tag>, por el cual se modifica su valor.Sí, técnicamente estamos modificando los valores de todo aquí, pero un vacío de inicio/final es mucho más probable que sea importante.Ahora utiliza dos separados, ligeramente más estricta de las búsquedas para evitar que.

Todavía tiene el "no depender de externos ordenada", etc.Sin embargo, sí requiere cl para el incf macro.

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

Una forma de hacerlo es Si usted tiene algo en formato de abajo

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

En Emacs, trate de

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

Esto guión por encima de xml de ejemplo a continuación

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

En VIM usted puede hacer esto mediante la

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

Espero que esto ayude.

  1. Emacs nxml modo puede trabajar en formato presentado, pero vas a tener que dividir las líneas.
  2. Para más archivos que simplemente no vale la pena.Ejecutar esta hoja de estilos (idealmente con Saxon que en mi humilde opinión, se obtiene la línea de guiones sobre la derecha) contra más archivos para obtener una bonita impresión.Para cualquiera de los elementos que desea conservar el espacio en blanco añadir sus nombres junto con la "programlisting" como en "programlisting yourElementName'

HTH

Tomé Jason Viers' versión y añadió que la lógica de poner xmlns declaraciones en sus propias líneas.Esto supone que ha xmlns= y xmlns:con no intervenir en los espacios en blanco.

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

Ordenado se ve como un buen modo.Debe mirar.Va a usar si realmente necesita todas las características que ofrece.

De todos modos, este problema estaba molestando por alrededor de una semana y yo no estaba buscando correctamente.Después de la publicación, empecé a buscar y encontré un sitio con un elisp función lo que lo hace bastante bien.El autor también sugiere el uso Ordenado.

Gracias por la respuesta Marcel (lástima que no tengo puntos suficientes para upmod usted).

Publicaremos pronto acerca de eso en mi blog. Aquí es un post sobre ello (con un enlace a Marcel sitio).

Yo uso xml-reformat-tags de xml-parse.el.Por lo general, usted va a querer tener el punto en el principio del archivo cuando se ejecuta este comando.

Es interesante que el archivo está incorporado en Emacspeak.Cuando yo estaba con Emacspeak en el día a día, pensé que xml-reformat-tags es una Emacs builtin.Un día me perdí y tuve que hacer una búsqueda en internet para que, y por lo tanto entró en la página de la wiki se mencionó anteriormente.

Estoy adjuntando también mi código para iniciar xml-parse.No estoy seguro si esta es la mejor pieza de código Emacs, pero parece que funciona para mí.

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

Si usted utiliza spacemacs, sólo tiene que utilizar el comando 'spacemacs/guión-región-o-buffer'.

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

Me temo que, como Benjamin Ferrari versión mucho mejor.La interna bastante impresión siempre coloca el extremo de la etiqueta en una nueva línea después de que el valor, la inserción no deseados CR en la etiqueta de valores.

como de 2017 emacs ya viene con esta capacidad por defecto, pero usted tiene que escribir esta pequeña función en el ~/.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))))

a continuación, sólo llame M-x reformat-xml

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top