How to colorize an xml by code

The following class will help you to do that.

You can easily transform this :

<?xml version="1.0" encoding="UTF-8"?>
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
     http://www.kde.org/standards/kcfg/1.0/kcfg.xsd">
    <kcfgfile name=""/>
    <group name="com.librehat.yahooweather">
        <entry name="woeid" type="String">
            <default></default>
        </entry>
        <entry name="interval" type="Int">
            <default>60</default>
        </entry>
        <entry name="celsius" type="Bool">
            <default>true</default>
        </entry>
        <entry name="fahrenheit" type="Bool">
            <default>false</default>
        </entry>
        <entry name="ms" type="Bool">
            <default>false</default>
        </entry>
        <entry name="kmh" type="Bool">
            <default>true</default>
        </entry>
    </group>
</kcfg>

Into this :

coloredxml

import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class XmlInColorsConverter {

    public static void main (String [] args) throws IOException {
        Scanner scanner = new Scanner(new File(args[0]));
        scanner.useDelimiter("\\A");
        System.out.println(new XmlInColorsConverter().convert(scanner.next()));
    }

    private static final Pattern NAME = Pattern.compile("(?:([a-zA-Z][a-zA-Z0-9]+):)?([a-zA-Z][a-zA-Z0-9._]+)");
    private static final Pattern VAL = Pattern.compile("\"((?:[^\"]|(?< =\\\\)\")*)\"");
    private static final Pattern ATTR = Pattern.compile("(" + NAME + ")\\s*(=)\\s*(" + VAL + ")\\s*");
    private static final Pattern MARKUP = Pattern.compile("(\\s*)(< )(/|\\?)?" + NAME + "\\s*(?:" + ATTR + ")*(/|\\?)?>");

    public String convert(String text) {
        return colorize(text, MARKUP.matcher(text));
    }

    private static String colorize(String input, Matcher matcher) {
        int lastEnd = 0;
        int level = 0;
        StringBuilder result = new StringBuilder();
        while (matcher.find()) {
            String oneMarkup = matcher.group();
            Matcher attrMatcher = ATTR.matcher(oneMarkup);
            String afterLastMatch = input.substring(lastEnd, matcher.start(2) == -1 ? 0 : matcher.start(2));
            level -= "/".equals(matcher.group(3)) ? 1 : 0;
            if (afterLastMatch.matches("\\s*")) {
                result.append("\n").append(IntStream.range(0, level).boxed().map(i -> "    ").collect(Collectors.joining()));
            }else {
                result.append(afterLastMatch);
            }
            level += matcher.group(3) == null ? 1 : 0;
            result.append("\033[1;33m< ").append((matcher.group(3) != null ? matcher.group(3) : "")).append((matcher.group(4) != null ?  "\033[34m" + matcher.group(4) + "\033[1;33m:" : "\033[1;33m")).append(matcher.group(5)).append("\033[0m");
            while (attrMatcher.find()) {
                result.append(" ").append((attrMatcher.group(2) != null ? "\033[34m" + attrMatcher.group(2) + "\033[35m:" : "\033[35m")).append(attrMatcher.group(3)).append("\033[32m=\033[36m").append(attrMatcher.group(5));
            }
            level -= "/".equals(matcher.group(12)) ? 1 : 0;
            result.append("\033[1;33m").append((matcher.group(12) != null ? matcher.group(12) : "")).append(">\033[0m");
            lastEnd = input.charAt(matcher.end()) == '\n' ? matcher.end() + 1 : matcher.end();
        }
        return result.toString();
    }
}

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*