Pergunta

Eu uso emacs para editar meus arquivos xml (nxml-mode) e os arquivos foram gerados pela máquina não tem qualquer muito formatação das tags.

Eu tenho pesquisado muito a impressão de que todo o arquivo com o recuo e salvá-lo, mas não era capaz de encontrar uma maneira automática.

Existe uma maneira?Ou pelo menos algum editor em linux que pode fazê-lo.

Foi útil?

Solução

Eu uso nXML modo para edição e Arrumado quando eu quero formato e travessão, XML ou HTML.Há também um interface Emacs para Arrumar.

Outras dicas

Você não precisa mesmo de escrever sua própria função - sgml-modo (gnu emacs módulo de núcleo) tem um built-in bastante função de impressão de chamada (sgml-pretty-print...), o que leva a região de início e de fim argumentos.

Se você está cortando e colando xml e você encontrar o seu terminal é cortar as linhas arbitrárias lugares você pode usar esse pretty printer que corrige linhas quebradas em primeiro lugar.

Se você só precisa muito de recuo sem a introdução de qualquer novo quebras de linha, você pode aplicar o indent-region comando para o buffer inteiro com essas combinações de teclas:

C-x h
C-M-\

Se você também precisa de introduzir quebras de linha, de modo que a abertura e fechamento de tags estão em linhas separadas, você pode usar o seguinte muito bom diretī orio elisp função, escrito por Benjamin Ferrari.Eu encontrei-o no seu blog e espero que ele é ok para mim reproduzi-la aqui:

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

Isso não depende de uma ferramenta externa, como Arrumar.

Emacs pode executar comandos arbitrários com M-|.Se você tem xmllint instalado:

"M-| xmllint --format -" irá formatar a região selecionada

"C-u-M| xmllint --format -" vai fazer o mesmo, substituindo a região com a saída de

Graças a Tim Helmstedt acima eu fiz st 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 e fácil.Muito obrigado.

Para introduzir quebras de linha e, em seguida, bonita impressão

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

eis alguns ajustes que eu fiz para Benjamin Ferrari versão:

  • o search-forward-regexp não especificar um fim, então ele teria de operar em coisas do começo da região a fim de buffer (em vez do fim da região)
  • Agora incrementos de end corretamente, como Cheeso observou.
  • seria inserir uma pausa entre <tag></tag>, o que modifica o seu valor.Sim, tecnicamente estamos modificando os valores de tudo aqui, mas um vazio de início/final é muito mais provável de ser significativo.Agora usa dois separados, um pouco mais rigorosas pesquisas para evitar isso.

Ainda tem o "não dependem externas arrumado", etc.No entanto, ele requer cl para o 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!"))

Uma forma de o fazer é Se você tem algo em formato abaixo

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

No Emacs, tente

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

Isto irá travessão acima xml de exemplo abaixo

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

No VIM, você pode fazer isso

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

Espero que isso ajude.

  1. Emacs nxml-modo de trabalho no formato apresentado, mas que você vai ter que dividir as linhas.
  2. Para mais arquivos que simplesmente não vale a pena.Executar esta folha de estilos (de preferência, com Saxon que IMHO obtém a linha de avanços sobre a direita) contra mais arquivos para se ter uma boa impressão bonita.Para quaisquer elementos onde você deseja manter espaço em branco adicionar seus nomes ao lado de "programlisting' como em 'programlisting yourElementName'

HTH

Eu levei Jason Viers' versão e acrescentou lógica para colocar xmlns declarações sobre suas próprias linhas.Isso pressupõe que você tenha xmlns= e xmlns:sem nenhum espaço em branco.

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

Arrumado parece um bom modo.Deve olhar para ele.Irá usá-lo se eu realmente precisar de todos os recursos que ela oferece.

De qualquer maneira, este problema foi a chatear-me para cerca de uma semana e eu não estava procurando corretamente.Após a postagem, comecei a pesquisar e encontrei um site com uma diretī orio elisp função o que não é muito bom.O autor também sugere o uso de Arrumado.

Obrigado pela resposta Marcel (pena que eu não tenho pontos suficientes para upmod você).

Vou postar sobre isso em breve no meu blog. Aqui é um post sobre isso (com um link para Marcel do site).

Eu uso xml-reformat-tags a partir de xml-analisar.el.Geralmente, você vai querer ter o ponto no início do arquivo quando o executar este comando.

É interessante que o arquivo está incorporada O Emacspeak.Quando eu estava utilizando o Emacspeak no dia-a-dia, eu pensei xml-reformat-tags é um Emacs builtin.Um dia eu perdi e tive que fazer uma pesquisa na internet para que, e, assim, entrou a página wiki mencionado acima.

Estou anexando também o meu código para iniciar o xml-analisar.Não sei se isso é o melhor pedaço do Emacs código, mas parece funcionar para mim.

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

Se você usar spacemacs, é só usar o comando 'spacemacs/recuo-região-ou-buffer'.

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

Eu tenho medo de como Benjamin Ferrari versão muito melhor.A interna impressão bonita de sempre coloca a tag de fim em uma nova linha após o valor, inserindo indesejados CR nos valores de marca.

como de 2017 emacs já vem com esse recurso por padrão, mas você tem para escrever esta pequena função para a ~/.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))))

em seguida, basta chamar M-x reformat-xml

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top