From 294c16be1b8f66ecea6c09cefe202f06219fa0ae Mon Sep 17 00:00:00 2001 From: Douglas Crockford Date: Tue, 4 Oct 2011 21:03:39 -0700 Subject: [PATCH] hygiene --- JSONML.java | 582 ++++++++++++++++++++++++++-------------------------- 1 file changed, 291 insertions(+), 291 deletions(-) diff --git a/JSONML.java b/JSONML.java index 3707191..72a6ac1 100755 --- a/JSONML.java +++ b/JSONML.java @@ -28,14 +28,14 @@ import java.util.Iterator; /** - * This provides static methods to convert an XML text into a JSONArray or - * JSONObject, and to covert a JSONArray or JSONObject into an XML text using + * This provides static methods to convert an XML text into a JSONArray or + * JSONObject, and to covert a JSONArray or JSONObject into an XML text using * the JsonML transform. * @author JSON.org - * @version 2011-10-03 + * @version 2011-10-04 */ public class JSONML { - + /** * Parse XML values and store them in a JSONArray. * @param x The XMLTokener containing the source string. @@ -46,185 +46,185 @@ public class JSONML { * @throws JSONException */ private static Object parse( - XMLTokener x, - boolean arrayForm, - JSONArray ja + XMLTokener x, + boolean arrayForm, + JSONArray ja ) throws JSONException { String attribute; char c; - String closeTag = null; + String closeTag = null; int i; JSONArray newja = null; JSONObject newjo = null; Object token; - String tagName = null; - + String tagName = null; + // Test for and skip past these forms: // // // // - + while (true) { - token = x.nextContent(); - if (token == XML.LT) { - token = x.nextToken(); - if (token instanceof Character) { - if (token == XML.SLASH) { + token = x.nextContent(); + if (token == XML.LT) { + token = x.nextToken(); + if (token instanceof Character) { + if (token == XML.SLASH) { // Close tag "); - } - x.back(); - } else if (c == '[') { - token = x.nextToken(); - if (token.equals("CDATA") && x.next() == '[') { - if (ja != null) { - ja.put(x.nextCDATA()); - } - } else { - throw x.syntaxError("Expected 'CDATA['"); - } - } else { - i = 1; - do { - token = x.nextMeta(); - if (token == null) { - throw x.syntaxError("Missing '>' after ' 0); - } - } else if (token == XML.QUEST) { + + c = x.next(); + if (c == '-') { + if (x.next() == '-') { + x.skipPast("-->"); + } + x.back(); + } else if (c == '[') { + token = x.nextToken(); + if (token.equals("CDATA") && x.next() == '[') { + if (ja != null) { + ja.put(x.nextCDATA()); + } + } else { + throw x.syntaxError("Expected 'CDATA['"); + } + } else { + i = 1; + do { + token = x.nextMeta(); + if (token == null) { + throw x.syntaxError("Missing '>' after ' 0); + } + } else if (token == XML.QUEST) { // "); - } else { - throw x.syntaxError("Misshaped tag"); - } + x.skipPast("?>"); + } else { + throw x.syntaxError("Misshaped tag"); + } // Open tag < - } else { - if (!(token instanceof String)) { - throw x.syntaxError("Bad tagName '" + token + "'."); - } - tagName = (String)token; - newja = new JSONArray(); - newjo = new JSONObject(); - if (arrayForm) { - newja.put(tagName); - if (ja != null) { - ja.put(newja); - } - } else { - newjo.put("tagName", tagName); - if (ja != null) { - ja.put(newjo); - } - } - token = null; - for (;;) { - if (token == null) { - token = x.nextToken(); - } - if (token == null) { - throw x.syntaxError("Misshaped tag"); - } - if (!(token instanceof String)) { - break; - } + } else { + if (!(token instanceof String)) { + throw x.syntaxError("Bad tagName '" + token + "'."); + } + tagName = (String)token; + newja = new JSONArray(); + newjo = new JSONObject(); + if (arrayForm) { + newja.put(tagName); + if (ja != null) { + ja.put(newja); + } + } else { + newjo.put("tagName", tagName); + if (ja != null) { + ja.put(newjo); + } + } + token = null; + for (;;) { + if (token == null) { + token = x.nextToken(); + } + if (token == null) { + throw x.syntaxError("Misshaped tag"); + } + if (!(token instanceof String)) { + break; + } // attribute = value - attribute = (String)token; - if (!arrayForm && (attribute == "tagName" || attribute == "childNode")) { - throw x.syntaxError("Reserved attribute."); - } - token = x.nextToken(); - if (token == XML.EQ) { - token = x.nextToken(); - if (!(token instanceof String)) { - throw x.syntaxError("Missing value"); - } - newjo.accumulate(attribute, XML.stringToValue((String)token)); - token = null; - } else { - newjo.accumulate(attribute, ""); - } - } + attribute = (String)token; + if (!arrayForm && (attribute == "tagName" || attribute == "childNode")) { + throw x.syntaxError("Reserved attribute."); + } + token = x.nextToken(); + if (token == XML.EQ) { + token = x.nextToken(); + if (!(token instanceof String)) { + throw x.syntaxError("Missing value"); + } + newjo.accumulate(attribute, XML.stringToValue((String)token)); + token = null; + } else { + newjo.accumulate(attribute, ""); + } + } if (arrayForm && newjo.length() > 0) { - newja.put(newjo); + newja.put(newjo); } // Empty tag <.../> - if (token == XML.SLASH) { - if (x.nextToken() != XML.GT) { - throw x.syntaxError("Misshaped tag"); - } - if (ja == null) { - if (arrayForm) { - return newja; - } else { - return newjo; - } - } + if (token == XML.SLASH) { + if (x.nextToken() != XML.GT) { + throw x.syntaxError("Misshaped tag"); + } + if (ja == null) { + if (arrayForm) { + return newja; + } else { + return newjo; + } + } // Content, between <...> and - } else { - if (token != XML.GT) { - throw x.syntaxError("Misshaped tag"); - } - closeTag = (String)parse(x, arrayForm, newja); - if (closeTag != null) { - if (!closeTag.equals(tagName)) { - throw x.syntaxError("Mismatched '" + tagName + - "' and '" + closeTag + "'"); - } - tagName = null; - if (!arrayForm && newja.length() > 0) { - newjo.put("childNodes", newja); - } - if (ja == null) { - if (arrayForm) { - return newja; - } else { - return newjo; - } - } - } - } - } - } else { - if (ja != null) { - ja.put(token instanceof String ? - XML.stringToValue((String)token) : token); - } - } + } else { + if (token != XML.GT) { + throw x.syntaxError("Misshaped tag"); + } + closeTag = (String)parse(x, arrayForm, newja); + if (closeTag != null) { + if (!closeTag.equals(tagName)) { + throw x.syntaxError("Mismatched '" + tagName + + "' and '" + closeTag + "'"); + } + tagName = null; + if (!arrayForm && newja.length() > 0) { + newjo.put("childNodes", newja); + } + if (ja == null) { + if (arrayForm) { + return newja; + } else { + return newjo; + } + } + } + } + } + } else { + if (ja != null) { + ja.put(token instanceof String ? + XML.stringToValue((String)token) : token); + } + } } } @@ -242,7 +242,7 @@ public class JSONML { * @throws JSONException */ public static JSONArray toJSONArray(String string) throws JSONException { - return toJSONArray(new XMLTokener(string)); + return toJSONArray(new XMLTokener(string)); } @@ -259,16 +259,16 @@ public class JSONML { * @throws JSONException */ public static JSONArray toJSONArray(XMLTokener x) throws JSONException { - return (JSONArray)parse(x, true, null); + return (JSONArray)parse(x, true, null); } - + /** * Convert a well-formed (but not necessarily valid) XML string into a * JSONObject using the JsonML transform. Each XML tag is represented as - * a JSONObject with a "tagName" property. If the tag has attributes, then - * the attributes will be in the JSONObject as properties. If the tag - * contains children, the object will have a "childNodes" property which + * a JSONObject with a "tagName" property. If the tag has attributes, then + * the attributes will be in the JSONObject as properties. If the tag + * contains children, the object will have a "childNodes" property which * will be an array of strings and JsonML JSONObjects. * Comments, prologs, DTDs, and <[ [ ]]> are ignored. @@ -277,16 +277,16 @@ public class JSONML { * @throws JSONException */ public static JSONObject toJSONObject(XMLTokener x) throws JSONException { - return (JSONObject)parse(x, false, null); + return (JSONObject)parse(x, false, null); } - - + + /** * Convert a well-formed (but not necessarily valid) XML string into a * JSONObject using the JsonML transform. Each XML tag is represented as - * a JSONObject with a "tagName" property. If the tag has attributes, then - * the attributes will be in the JSONObject as properties. If the tag - * contains children, the object will have a "childNodes" property which + * a JSONObject with a "tagName" property. If the tag has attributes, then + * the attributes will be in the JSONObject as properties. If the tag + * contains children, the object will have a "childNodes" property which * will be an array of strings and JsonML JSONObjects. * Comments, prologs, DTDs, and <[ [ ]]> are ignored. @@ -295,7 +295,7 @@ public class JSONML { * @throws JSONException */ public static JSONObject toJSONObject(String string) throws JSONException { - return toJSONObject(new XMLTokener(string)); + return toJSONObject(new XMLTokener(string)); } @@ -306,156 +306,156 @@ public class JSONML { * @throws JSONException */ public static String toString(JSONArray ja) throws JSONException { - int i; - JSONObject jo; - String key; - Iterator keys; - int length; - Object object; - StringBuffer sb = new StringBuffer(); - String tagName; - String value; - -// Emit = length) { - sb.append('/'); - sb.append('>'); - } else { - sb.append('>'); - do { - object = ja.get(i); - i += 1; - if (object != null) { - if (object instanceof String) { - sb.append(XML.escape(object.toString())); - } else if (object instanceof JSONObject) { - sb.append(toString((JSONObject)object)); - } else if (object instanceof JSONArray) { - sb.append(toString((JSONArray)object)); - } - } - } while (i < length); - sb.append('<'); - sb.append('/'); - sb.append(tagName); - sb.append('>'); - } + + length = ja.length(); + if (i >= length) { + sb.append('/'); + sb.append('>'); + } else { + sb.append('>'); + do { + object = ja.get(i); + i += 1; + if (object != null) { + if (object instanceof String) { + sb.append(XML.escape(object.toString())); + } else if (object instanceof JSONObject) { + sb.append(toString((JSONObject)object)); + } else if (object instanceof JSONArray) { + sb.append(toString((JSONArray)object)); + } + } + } while (i < length); + sb.append('<'); + sb.append('/'); + sb.append(tagName); + sb.append('>'); + } return sb.toString(); } - + /** * Reverse the JSONML transformation, making an XML text from a JSONObject. - * The JSONObject must contain a "tagName" property. If it has children, - * then it must have a "childNodes" property containing an array of objects. + * The JSONObject must contain a "tagName" property. If it has children, + * then it must have a "childNodes" property containing an array of objects. * The other properties are attributes with string values. * @param jo A JSONObject. * @return An XML string. * @throws JSONException */ - public static String toString(JSONObject jo) throws JSONException { - StringBuffer sb = new StringBuffer(); - int i; - JSONArray ja; - String key; - Iterator keys; - int length; - Object object; - String tagName; - String value; - + public static String toString(JSONObject jo) throws JSONException { + StringBuffer sb = new StringBuffer(); + int i; + JSONArray ja; + String key; + Iterator keys; + int length; + Object object; + String tagName; + String value; + //Emit '); - } else { - sb.append('>'); - length = ja.length(); - for (i = 0; i < length; i += 1) { - object = ja.get(i); - if (object != null) { - if (object instanceof String) { - sb.append(XML.escape(object.toString())); - } else if (object instanceof Number) { - sb.append(object.toString()); + + ja = jo.optJSONArray("childNodes"); + if (ja == null) { + sb.append('/'); + sb.append('>'); + } else { + sb.append('>'); + length = ja.length(); + for (i = 0; i < length; i += 1) { + object = ja.get(i); + if (object != null) { + if (object instanceof String) { + sb.append(XML.escape(object.toString())); } else if (object instanceof JSONObject) { sb.append(toString((JSONObject)object)); - } else if (object instanceof JSONArray) { - sb.append(toString((JSONArray)object)); - } - } - } - sb.append('<'); - sb.append('/'); - sb.append(tagName); - sb.append('>'); - } + } else if (object instanceof JSONArray) { + sb.append(toString((JSONArray)object)); + } else { + sb.append(object.toString()); + } + } + } + sb.append('<'); + sb.append('/'); + sb.append(tagName); + sb.append('>'); + } return sb.toString(); } } \ No newline at end of file