7
votes

Java Supprimer les tags XML vides

Je recherche un simple extrait Java pour éliminer les étiquettes vides d'une structure xml xxx

devrait devenir; xxx


2 commentaires

Avez-vous actuellement l'analyse du XML dans des structures de données de manière particulière (JDOM, etc.)? Ou commencez-vous à partir de zéro?


TYPO Dans l'exemple XML: Structure1 n'est pas correctement fermé


9 Réponses :


0
votes

avec XSLT, vous pouvez transformer votre XML pour ignorer les balises vides et ré-écrire le document.


0 commentaires

8
votes

Cette feuille de style Xslt devrait faire ce que vous recherchez:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="@*|node()">
    <xsl:if test=". != '' or ./@* != ''">
      <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>


0 commentaires

7
votes

Je me demandais s'il serait facile de le faire avec le Bibliothèque XOM et a donné un essai .

Il s'est avéré être assez facile: p> xxx pré>

Cela ne traitera probablement pas correctement tous les cas d'angle, comme un document complètement vide. Et quoi faire sur les éléments qui sont autrement vides mais ont des attributs? P>

Si vous souhaitez enregistrer des balises XML avec des attributs, nous pouvons ajouter dans la méthode "Handlenode". Vérifier: P>

... && ((Element) node).getAttributeCount() == 0) )


0 commentaires

3
votes

Note latérale: Les différents états d'une étiquette ont en fait de la signification:

  • Étiquette ouverte: L'élément existe et sa valeur est une chaîne vide
  • Single-Tag: L'élément existe, mais la valeur est null ou nil
  • étiquette manquante: L'élément n'existe pas

    Donc, en supprimant des étiquettes et des étiquettes à open-fermées vides, vous les fusionnez avec le groupe de balises manquantes et perdez ainsi des informations.


2 commentaires

Très bon point - il est parfois utile de supprimer les étiquettes dont la valeur est vide ou null, mais il y a aussi des moments où cela pourrait être potentiellement préjudiciable à l'application.


Pour mon but, cela n'est pas pertinent



1
votes

Si le XML est alimenté comme chaîne; Regex pourrait être utilisé pour filtrer les éléments vides: xxx

Ceci trouvera des éléments vides. xxx

données dans ce cas une variable contenant votre String XML. de
Ne disant pas que ce serait le meilleur des solutions, mais c'est possible ...


0 commentaires

1
votes

Je devais ajouter des éléments de bandes et d'indents à la réponse de Chris R, sinon les blocs englobent, nouvellement vide, ne sont pas supprimés:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes" />
  <xsl:template match="@*|node()">
    <xsl:if test=". != '' or ./@* != ''">
      <xsl:copy>
        <xsl:apply-templates  select="@*|node()"/>
      </xsl:copy>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>


0 commentaires

0
votes

Pour supprimer toutes les balises vides, même si elles sont l'une après l'autre, une solution possible est la suivante:

 private void removeEmptyTags(Document document) {
    List<Node> listNode = new ArrayList<Node>();
    findListEmptyTags(document.getRootElement(), listNode);
    if (listNode.size() == 0)
        return;

    for (Node node : listNode) {
        node.getParent().removeChild(node);
    }
    removeEmptyTags(document);
}

private void findListEmptyTags(Node node, List<Node> listNode) {

    if (node != null && node.getChildCount() == 0 && "".equals(node.getValue()) && ((Element) node).getAttributeCount() == 0) {
        listNode.add(node);
        return;
    }
    // recurse the children
    for (int i = 0; i < node.getChildCount(); i++) {
        findListEmptyTags(node.getChild(i), listNode);
    }
}


0 commentaires

2
votes

J'ai testé les tests d'échantillons de Jonik et Marco. Mais ce ne sont pas exactement ce que je veux. J'ai donc modifié leur source et ci-dessous le code fonctionne bien pour moi. J'ai déjà ajusté ce code dans mon projet. Veuillez le tester si vous voulez.

public String removeEmptyNode(String xml){
    String cleanedXml = null;
    try{
        xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + xml;
        InputStream input = new ByteArrayInputStream(xml.getBytes("UTF-8"));
        Document document = new Builder().build(input);
        removeEmptyNode(document.getRootElement());
        cleanedXml = document.toXML();
    }catch(Exception e){
        e.printStackTrace();
    }
    return cleanedXml;
}

private static void removeEmptyNode(Node node) {
    if(node.getChildCount()!=0){
        int count = node.getChildCount();
        for (int i = count-1; i >= 0 ; i--) { 
            removeEmptyNode(node.getChild(i));
        }
    }

    doCheck(node);
}

private static void doCheck(Node node){
    if(node.getChildCount() == 0 && "".equals(node.getValue().trim())) {
        try{node.getParent().removeChild(node);}catch(Exception e){}
    }       
}


0 commentaires

0
votes
<xml>
    <field1>bla</field1>
    <field2></field2>
    <field3/>
    <structure1>
        <field4>
            <field50>
                <field60/>
            </field50>
        </field4>
        <field5></field5>
    </structure1>
</xml>

<xml>
    <field1>bla</field1>
</xml>

0 commentaires