web-dev-qa-db-fra.com

comment décoder XML en Java

Je dois extraire une chaîne xml contenant des balises XML échappées:

<
>
&
etc...

J'ai trouvé des bibliothèques capables d'effectuer cette tâche, mais je préférerais utiliser une seule méthode pour effectuer cette tâche.

Quelqu'un peut aider?

acclamations, Bas Hendriks

24
Bas Hendriks
StringEscapeUtils.unescapeXml(xml)

( commons-lang , télécharger )

43
Bozho

Voici une méthode simple pour décompresser XML. Il gère les entités XML prédéfinies et les entités numériques décimales (& # nnnn;). Le modifier pour gérer les entités hexagonales (& # xhhhh;) devrait être simple.

public static String unescapeXML( final String xml )
{
    Pattern xmlEntityRegex = Pattern.compile( "&(#?)([^;]+);" );
    //Unfortunately, Matcher requires a StringBuffer instead of a StringBuilder
    StringBuffer unescapedOutput = new StringBuffer( xml.length() );

    Matcher m = xmlEntityRegex.matcher( xml );
    Map<String,String> builtinEntities = null;
    String entity;
    String hashmark;
    String ent;
    int code;
    while ( m.find() ) {
        ent = m.group(2);
        hashmark = m.group(1);
        if ( (hashmark != null) && (hashmark.length() > 0) ) {
            code = Integer.parseInt( ent );
            entity = Character.toString( (char) code );
        } else {
            //must be a non-numerical entity
            if ( builtinEntities == null ) {
                builtinEntities = buildBuiltinXMLEntityMap();
            }
            entity = builtinEntities.get( ent );
            if ( entity == null ) {
                //not a known entity - ignore it
                entity = "&" + ent + ';';
            }
        }
        m.appendReplacement( unescapedOutput, entity );
    }
    m.appendTail( unescapedOutput );

    return unescapedOutput.toString();
}

private static Map<String,String> buildBuiltinXMLEntityMap()
{
    Map<String,String> entities = new HashMap<String,String>(10);
    entities.put( "lt", "<" );
    entities.put( "gt", ">" );
    entities.put( "amp", "&" );
    entities.put( "apos", "'" );
    entities.put( "quot", "\"" );
    return entities;
}
6
texclayton

En voici une que j'ai écrite en dix minutes. Il n'utilise pas d'expressions régulières, seulement des itérations simples. Je ne pense pas que cela puisse être amélioré pour être beaucoup plus rapide.

public static String unescape(final String text) {
    StringBuilder result = new StringBuilder(text.length());
    int i = 0;
    int n = text.length();
    while (i < n) {
        char charAt = text.charAt(i);
        if (charAt != '&') {
            result.append(charAt);
            i++;
        } else {
            if (text.startsWith("&amp;", i)) {
                result.append('&');
                i += 5;
            } else if (text.startsWith("&apos;", i)) {
                result.append('\'');
                i += 6;
            } else if (text.startsWith("&quot;", i)) {
                result.append('"');
                i += 6;
            } else if (text.startsWith("&lt;", i)) {
                result.append('<');
                i += 4;
            } else if (text.startsWith("&gt;", i)) {
                result.append('>');
                i += 4;
            } else i++;
        }
    }
    return result.toString();
}
4
Balazs Zsoldos

Si vous travaillez avec JSP, utilisez su: unescapeXml from openutils-elfunctions

0
msangel