J'ai une chaîne Java qui contient du XML, sans sauts de ligne ni indentations. Je voudrais le transformer en une chaîne avec du XML bien formaté. Comment puis-je faire cela?
String unformattedXml = "<tag><nested>hello</nested></tag>";
String formattedXml = new [UnknownClass]().format(unformattedXml);
Remarque: Mon entrée est un chaîne . Ma sortie est une chaîne .
Résultat de simulation (de base):
<?xml version="1.0" encoding="UTF-8"?>
<root>
<tag>
<nested>hello</nested>
</tag>
</root>
java
xml
pretty-print
Steve McLeod
la source
la source
Réponses:
Remarque: les résultats peuvent varier selon la version Java. Recherchez des solutions de contournement spécifiques à votre plateforme.
la source
<?xml version="1.0" encoding="UTF-8"?>
?<?xml ...>
déclaration, ajouteztransformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes")
doc
défini?Voici une réponse à ma propre question. J'ai combiné les réponses des différents résultats pour écrire une classe qui imprime assez XML.
Aucune garantie sur la façon dont il répond avec XML non valide ou des documents volumineux.
la source
writer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE);
après laLSSerializer writer = ...
ligne.document
été initialisée, j'ai donc pensé pouvoir ajouter la décélération et en faire un exemple rapide. Faites-moi savoir si je dois changer quelque chose, pastebin.com/XL7932aCune solution plus simple basée sur cette réponse :
cas de test:
Retour:
la source
factory.setAttribute("indent-number", 4);
et maintenant cela fonctionne.<?xml version="1.0" encoding="UTF-8"?>
?transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
<?xml version="1.0" encoding="UTF-8"?><root>
est tout sur une seule ligne. Des idées pourquoi?transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "yes");
fonctionné pour moi.Maintenant que c'est 2012 et Java peut faire plus qu'avant avec XML, je voudrais ajouter une alternative à ma réponse acceptée. Cela n'a pas de dépendances en dehors de Java 6.
la source
Juste pour noter que la réponse la mieux notée nécessite l'utilisation de xerces.
Si vous ne voulez pas ajouter cette dépendance externe, vous pouvez simplement utiliser les bibliothèques jdk standard (qui sont en fait construites en utilisant xerces en interne).
NB Il y avait un bogue avec la version 1.5 de jdk voir http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6296446 mais il est résolu maintenant.,
(Notez que si une erreur se produit, cela retournera le texte d'origine)
la source
J'ai assez imprimé dans le passé en utilisant la méthode org.dom4j.io.OutputFormat.createPrettyPrint ()
la source
prettyPrintedString.replaceAll("\\s+\n", "\n")
Voici une façon de le faire en utilisant dom4j :
Importations:
Code:
la source
<?xml version...
sur une ligne et tout le reste sur une autre ligne.Puisque vous commencez par un
String
, vous devez convertir unDOM
objet (par exempleNode
) avant de pouvoir utiliser leTransformer
. Cependant, si vous savez que votre chaîne XML est valide et que vous ne voulez pas encourir la surcharge de mémoire pour analyser une chaîne dans un DOM, puis exécuter une transformation sur le DOM pour récupérer une chaîne - vous pouvez simplement faire de l'ancienne analyse par caractère. Insérez une nouvelle ligne et des espaces après chaque</...>
caractère, gardez et indentez le compteur (pour déterminer le nombre d'espaces) que vous incrémentez pour chaque<...>
et décrémentez pour chaque que</...>
vous voyez.Avertissement - J'ai fait un copier / coller / éditer le texte des fonctions ci-dessous, donc elles peuvent ne pas compiler telles quelles.
la source
Si l'utilisation d'une bibliothèque XML tierce est correcte, vous pouvez vous en sortir avec quelque chose de beaucoup plus simple que ce que les réponses actuellement les plus votées suggèrent les .
Il a été déclaré que l'entrée et la sortie devraient être des chaînes, voici donc une méthode utilitaire qui fait exactement cela, implémentée avec la bibliothèque XOM :
J'ai testé que cela fonctionne, et les résultats ne dépendent pas de votre version JRE ou de quelque chose comme ça. Pour voir comment personnaliser le format de sortie à votre guise, jetez un œil à l'
Serializer
API.Cela est en fait sorti plus longtemps que je ne le pensais - quelques lignes supplémentaires étaient nécessaires parce que
Serializer
veutOutputStream
écrire. Mais notez qu'il y a très peu de code pour le twiddling XML réel ici.(Cette réponse fait partie de mon évaluation de XOM, qui a été suggérée comme une option dans ma question sur la meilleure bibliothèque XML Java pour remplacer dom4j. Pour mémoire, avec dom4j, vous pouvez y parvenir avec la même facilité en utilisant
XMLWriter
etOutputFormat
. Modifier : .. . comme démontré dans la réponse de mlo55 .)la source
Kevin Hakanson a déclaré: "Cependant, si vous savez que votre chaîne XML est valide et que vous ne voulez pas encourir la surcharge de mémoire pour analyser une chaîne dans un DOM, puis exécuter une transformation sur le DOM pour récupérer une chaîne - vous pourriez il suffit d'analyser les caractères à l'ancienne. Insérez une nouvelle ligne et des espaces après chaque caractère, gardez et indentez le compteur (pour déterminer le nombre d'espaces) que vous augmentez pour chaque <...> et décrémentez pour chaque que vous voyez. "
D'accord. Une telle approche est beaucoup plus rapide et a beaucoup moins de dépendances.
Exemple de solution:
la source
Hmmm ... face à quelque chose comme ça et c'est un bug connu ... il suffit d'ajouter ce OutputProperty ..
J'espère que cela t'aides ...
la source
Concernant le commentaire "vous devez d'abord construire une arborescence DOM": Non, vous n'avez pas besoin et ne devez pas le faire.
Au lieu de cela, créez un StreamSource (nouveau StreamSource (nouveau StringReader (str)) et alimentez-le au transformateur d'identité mentionné. Cela utilisera l'analyseur SAX, et le résultat sera beaucoup plus rapide. La construction d'un arbre intermédiaire est une surcharge pure pour ce cas. Sinon, la réponse la mieux classée est bonne.
la source
Utilisation de scala:
Vous pouvez également le faire en Java, si vous dépendez du scala-library.jar. Cela ressemble à ceci:
L'
PrettyPrinter
objet est construit avec deux pouces, le premier étant la longueur de ligne maximale et le second étant l'étape d'indentation.la source
version légèrement améliorée de milosmns ...
la source
} else if (row.startsWith("</")) {
partie pour cela:else if (row.startsWith("</")) { String indent = repeatIdent(--stack); if (pretty.charAt(pretty.length() - 1) == '\n') { pretty.append(indent + row + "\n"); } else { pretty.append(row + "\n"); } }
Juste pour référence future, voici une solution qui a fonctionné pour moi (grâce à un commentaire que @George Hawkins a posté dans l'une des réponses):
la source
Si vous êtes sûr d'avoir un XML valide, celui-ci est simple et évite les arborescences XML DOM. Peut-être a quelques bugs, commentez si vous voyez quelque chose
la source
Toutes les solutions ci-dessus ne fonctionnaient pas pour moi, alors j'ai trouvé ce http://myshittycode.com/2014/02/10/java-properly-indenting-xml-string/
L'indice est de supprimer les espaces blancs avec XPath
la source
Ce code ci-dessous fonctionne parfaitement
la source
Je les mélange tous et j'écris un petit programme. Il lit le fichier xml et l'imprime. Juste au lieu de xzy, donnez votre chemin de fichier.
la source
Juste une autre solution qui fonctionne pour nous
la source
Utilisation de jdom2: http://www.jdom.org/
la source
Comme alternative aux réponses de max , codeskraps , David Easley et milosmns , jetez un œil à ma bibliothèque de jolies imprimantes légères et hautes performances: xml-formatter
Parfois, comme lors de l'exécution de services SOAP simulés directement à partir d'un fichier, il est bon d'avoir une jolie imprimante qui gère également du XML déjà assez imprimé:
Comme certains l'ont commenté, la jolie impression n'est qu'un moyen de présenter XML sous une forme plus lisible par l'homme - les espaces n'appartiennent strictement pas à vos données XML.
La bibliothèque est conçue pour une jolie impression à des fins de journalisation, et comprend également des fonctions de filtrage (suppression / anonymisation de sous-arborescence) et de jolie impression de XML dans les nœuds CDATA et Texte.
la source
J'ai eu le même problème et j'ai beaucoup de succès avec JTidy ( http://jtidy.sourceforge.net/index.html )
Exemple:
la source
Underscore-java a une méthode statique
U.formatXml(string)
. Je suis le responsable du projet. Exemple en directProduction:
la source
il y a un très bon utilitaire xml en ligne de commande appelé xmlstarlet ( http://xmlstar.sourceforge.net/ ) qui peut faire beaucoup de choses que beaucoup de gens utilisent.
Vous pouvez exécuter ce programme par programme en utilisant Runtime.exec, puis lire le fichier de sortie formaté. Il a plus d'options et un meilleur rapport d'erreur que quelques lignes de code Java ne peuvent fournir.
téléchargez xmlstarlet: http://sourceforge.net/project/showfiles.php?group_id=66612&package_id=64589
la source
J'ai trouvé qu'en Java 1.6.0_32, la méthode normale pour imprimer une chaîne XML (en utilisant un Transformer avec un null ou une identité xslt) ne se comporte pas comme je le voudrais si les balises sont simplement séparées par des espaces, par opposition à ne pas avoir de séparation texte. J'ai essayé d'utiliser
<xsl:strip-space elements="*"/>
mon modèle en vain. La solution la plus simple que j'ai trouvée était de décaper l'espace comme je le souhaitais en utilisant un filtre SAXSource et XML. Étant donné que ma solution était pour la journalisation, j'ai également étendu cela pour travailler avec des fragments XML incomplets. Notez que la méthode normale semble fonctionner correctement si vous utilisez un DOMSource mais je ne voulais pas l'utiliser à cause de l'incomplétude et de la surcharge de mémoire.la source
Les solutions que j'ai trouvées ici pour Java 1.6+ ne reformatent pas le code s'il est déjà formaté. Celui qui a fonctionné pour moi (et a reformaté le code déjà formaté) était le suivant.
C'est un bon outil à utiliser dans vos tests unitaires pour la comparaison xml de chaîne complète.
la source
Pour ceux qui recherchent une solution rapide et sale - qui n'a pas besoin que le XML soit valide à 100%. par exemple en cas de journalisation REST / SOAP (on ne sait jamais ce que les autres envoient ;-))
J'ai trouvé et avancé un code coupé que j'ai trouvé en ligne et qui, je pense, manque toujours ici comme approche possible valide:
voici la sortie:
la source
J'ai vu une réponse utiliser
Scala
, alors voici une autreGroovy
, juste au cas où quelqu'un la trouverait intéressante. L'indentation par défaut est de 2 étapes, leXmlNodePrinter
constructeur peut également recevoir une autre valeur.Utilisation de Java si le pot groovy est dans le chemin de classe
la source
Dans le cas où vous n'avez pas besoin de beaucoup d'indentation mais de quelques sauts de ligne, il pourrait suffire de simplement regex ...
Le code est sympa, pas le résultat à cause d'une indentation manquante.
(Pour les solutions avec indentation, voir les autres réponses.)
la source