Preprocessor { public static String preProcessSchemaDefinition(BufferedReader reader) throws IOException {{ // First, just read the contents of the file into a string String content = ""; for (String line = reader.readLine(); line != null; line = reader.readLine()) { content = content + (content.equals("")?"":"\n") + line; } // Extract the Schema name space prefix from the contents String nsPrefix = ""; try { StringTokenizer st = new StringTokenizer(content, "<>: \t\n"); nsPrefix = st.nextToken(); if (nsPrefix.equals("schema")) nsPrefix = ""; else nsPrefix = nsPrefix + ":"; } catch (NoSuchElementException e) {} // Convert all "comments" to strings to enable parsing them as such content = stringifyComments(content); // Convert non-empty documentation elements to single strings content = stringifyCharContent(content, nsPrefix, "documentation"); // Insert the space character needed in the start tag (between the tag // name and the ">" character) for all elements that can have both empty // and non-empty contents, and has a non-empty content with no // attributes in this instance. This is needed for correct parsing. content = addSpaceAfterStartTag(content, nsPrefix, "any"); content = addSpaceAfterStartTag(content, nsPrefix, "attribute"); content = addSpaceAfterStartTag(content, nsPrefix, "complexType"); content = addSpaceAfterStartTag(content, nsPrefix, "documentation"); content = addSpaceAfterStartTag(content, nsPrefix, "duration"); content = addSpaceAfterStartTag(content, nsPrefix, "element"); content = addSpaceAfterStartTag(content, nsPrefix, "encoding"); content = addSpaceAfterStartTag(content, nsPrefix, "enumeration"); content = addSpaceAfterStartTag(content, nsPrefix, "field"); content = addSpaceAfterStartTag(content, nsPrefix, "import"); content = addSpaceAfterStartTag(content, nsPrefix, "include"); content = addSpaceAfterStartTag(content, nsPrefix, "length"); content = addSpaceAfterStartTag(content, nsPrefix, "list"); content = addSpaceAfterStartTag(content, nsPrefix, "maxExclusive"); content = addSpaceAfterStartTag(content, nsPrefix, "maxInclusive"); content = addSpaceAfterStartTag(content, nsPrefix, "maxLength"); content = addSpaceAfterStartTag(content, nsPrefix, "minExclusive"); content = addSpaceAfterStartTag(content, nsPrefix, "minInclusive"); content = addSpaceAfterStartTag(content, nsPrefix, "minLength"); content = addSpaceAfterStartTag(content, nsPrefix, "notation"); content = addSpaceAfterStartTag(content, nsPrefix, "pattern"); content = addSpaceAfterStartTag(content, nsPrefix, "period"); content = addSpaceAfterStartTag(content, nsPrefix, "precision"); content = addSpaceAfterStartTag(content, nsPrefix, "redefine"); content = addSpaceAfterStartTag(content, nsPrefix, "restriction"); content = addSpaceAfterStartTag(content, nsPrefix, "scale"); content = addSpaceAfterStartTag(content, nsPrefix, "selector"); content = addSpaceAfterStartTag(content, nsPrefix, "sequence"); content = addSpaceAfterStartTag(content, nsPrefix, "simpleContent"); content = addSpaceAfterStartTag(content, nsPrefix, "simpleType"); content = addSpaceAfterStartTag(content, nsPrefix, "union"); content = addSpaceAfterStartTag(content, nsPrefix, "whiteSpace"); // Replace the "\" in escape sequences contained in patterns by "$" // because it confuses the parser content = replacePattern(content, "\\d", "$DIGIT"); // All pre-processing done return content; }} private static String stringifyComments(String input) {{ String output = input; int startIndex = 0; for (int startTagIndex = output.indexOf("", startTagIndex+4); if (endTagIndex > startTagIndex) { int contentStartIndex = startTagIndex + 4; String content = output.substring(contentStartIndex, endTagIndex); content = " \"" + combineWhiteSpace(content) + "\" "; output = output.substring(0, contentStartIndex) + content + output.substring(endTagIndex); startIndex = contentStartIndex + content.length() + 3; } } return output; }} private static String stringifyCharContent(String input, String nsPrefix, String tag) {{ String startTagPattern = "<" + nsPrefix + tag; String endTagPattern = ""; String output = input; int startIndex = 0; for (int startTagIndex = output.indexOf(startTagPattern, startIndex); startTagIndex >= 0; startTagIndex = output.indexOf(startTagPattern, startIndex)) { int endTagIndex = output.indexOf(endTagPattern, startTagIndex+startTagPattern.length()); if (endTagIndex > startTagIndex) { int contentStartIndex = 1 + output.indexOf(">", startTagIndex+startTagPattern.length()); String content = output.substring(contentStartIndex, endTagIndex); content = " \"" + combineWhiteSpace(content) + "\" "; output = output.substring(0, contentStartIndex) + content + output.substring(endTagIndex); startIndex = contentStartIndex + content.length() + endTagPattern.length(); } } return output; }} private static String addSpaceAfterStartTag(String input, String nsPrefix, String tag) {{ return replacePattern(input, "<" + nsPrefix + tag + ">", "<" + nsPrefix + tag + " >"); }} private static String replacePattern(String input, String oldContent, String newContent) {{ String output = input; int startIndex = 0; for (int index = output.indexOf(oldContent, startIndex); index >= 0; index = output.indexOf(oldContent, startIndex)) { startIndex = index + newContent.length(); output = output.substring(0, index) + newContent + output.substring(index + oldContent.length()); } return output; }} private static String combineWhiteSpace(String input) {{ String output = ""; for (StringTokenizer st = new StringTokenizer(input, "\r\n\t "); st.hasMoreTokens(); ) { output = output + (output.equals("") ? "" : " ") + st.nextToken(); } return output; }} }