Java tutorial
//package com.java2s; //License from project: Open Source License import java.io.Writer; public class Main { /** * Unescape (and normalize) the given XML string. * * Only element content (excluding markup) and attributes (values) need to be unescaped. * Markup, comments, CDATA sections, and prosessing instructions need to be left unchanged. * * * @param writer The writer where the escaped string is written to. * @param str The given XML string (character text or attribute value; unescaped). */ private static void unescape(Writer writer, String str) throws Exception { // First, normalize end-of-line delimiters str = str.replaceAll("(?i)
", "
"); // case-insensitive matching str = str.replaceAll("(?i)
…", "
"); // case-insensitive matching str = str.replaceAll("(?i)…", "
"); // case-insensitive matching str = str.replaceAll("(?i)
", "
"); // case-insensitive matching str = str.replaceAll("(?i)
", "
"); // case-insensitive matching // Finally, unescape characters for (int i = 0; i < str.length(); i++) { char c = str.charAt(i); switch (c) { // ampersand: case '&': int nextIdx = i + 1; int semiColonIdx = str.indexOf(';', nextIdx); // Found ampersand did not start an entity, no following semi-colon exists if (semiColonIdx == -1) { // The the text looks like &... writer.write(c); continue; } int amphersandIdx = str.indexOf('&', nextIdx); // Found ampersand did not start an entity, no following semi-colon before next ampersand if (amphersandIdx != -1 && amphersandIdx < semiColonIdx) { // Then the text looks like &...&...; writer.write(c); continue; } String entityContent = str.substring(nextIdx, semiColonIdx); int entityValue = -1; if (entityContent.length() > 0) { // Escaped value content is an integer (decimal or hexadecimal) if (entityContent.charAt(0) == '#') { if (entityContent.length() > 1) { char isHexChar = entityContent.charAt(1); try { switch (isHexChar) { // hexadecimal, 16 base case 'X': case 'x': entityValue = Integer.parseInt(entityContent.substring(2), 16); break; // decimal, 10 base default: entityValue = Integer.parseInt(entityContent.substring(1), 10); } if (entityValue > 0xFFFF) { entityValue = -1; } } catch (NumberFormatException nfex) { entityValue = -1; } } } // Escaped value content is an entity name else { // less-than: if ("lt".equals(entityContent) == true) { entityValue = 60; } // ampersand: else if ("amp".equals(entityContent) == true) { entityValue = 38; } // greater-than: else if ("gt".equals(entityContent) == true) { entityValue = 62; } // single-quote: else if ("apos".equals(entityContent) == true) { entityValue = 39; } // double-quote: else if ("quot".equals(entityContent) == true) { entityValue = 34; } } } // Entity value was not found (not an XML entity value) if (entityValue == -1) { writer.write('&'); writer.write(entityContent); writer.write(';'); } // Entity value was found else { writer.write(entityValue); } i = semiColonIdx; // move index up to the semi-colon break; // else, default print char default: writer.write(c); } } } }