XML.java
上传用户:shen332233
上传日期:2021-09-03
资源大小:7478k
文件大小:12k
- package org.json;
- /*
- Copyright (c) 2002 JSON.org
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
- The Software shall be used for Good, not Evil.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
- import java.util.Iterator;
- import java.text.ParseException;
- /**
- * This provides static methods to convert an XML text into a JSONObject,
- * and to covert a JSONObject into an XML text.
- * @author JSON.org
- * @version 0.1
- */
- public class XML {
- private XML() {}
- /** The Character '&'. */
- public static final Character AMP = new Character('&');
- /** The Character '''. */
- public static final Character APOS = new Character(''');
- /** The Character '!'. */
- public static final Character BANG = new Character('!');
- /** The Character '='. */
- public static final Character EQ = new Character('=');
- /** The Character '>'. */
- public static final Character GT = new Character('>');
- /** The Character '<'. */
- public static final Character LT = new Character('<');
- /** The Character '?'. */
- public static final Character QUEST = new Character('?');
- /** The Character '"'. */
- public static final Character QUOT = new Character('"');
- /** The Character '/'. */
- public static final Character SLASH = new Character('/');
- /**
- * Replace special characters with XML escapes:
- * <pre>
- * & is replaced by &amp;
- * < is replaced by &lt;
- * > is replaced by &gt;
- * " is replaced by &quot;
- * </pre>
- */
- public static String escape(String string) {
- return string
- .replaceAll("&", "&")
- .replaceAll("<", "<")
- .replaceAll(">", ">")
- .replaceAll(""", """);
- }
- /**
- * Scan the content following the named tag, attaching it to the context.
- * @param x The XMLTokener containing the source string.
- * @param context The JSONObject that will include the new material.
- * @param name The tag name.
- * @return true if the close tag is processed.
- * @throws ParseException
- */
- private static boolean parse(XMLTokener x, JSONObject context,
- String name) throws ParseException {
- char c;
- int i;
- String n;
- JSONObject o;
- String s;
- Object t;
- // Test for and skip past these forms:
- // <!-- ... -->
- // <! ... >
- // <![ ... ]]>
- // <? ... ?>
- // Report errors for these forms:
- // <>
- // <=
- // <<
- t = x.nextToken();
- // <!
- if (t == BANG) {
- c = x.next();
- if (c == '-') {
- if (x.next() == '-') {
- x.skipPast("-->");
- return false;
- }
- x.back();
- } else if (c == '[') {
- x.skipPast("]]>");
- return false;
- }
- i = 1;
- do {
- t = x.nextMeta();
- if (t == null) {
- throw x.syntaxError("Missing '>' after '<!'.");
- } else if (t == LT) {
- i += 1;
- } else if (t == GT) {
- i -= 1;
- }
- } while (i > 0);
- return false;
- } else if (t == QUEST) {
- // <?
- x.skipPast("?>");
- return false;
- } else if (t == SLASH) {
- // Close tag </
- if (name == null || !x.nextToken().equals(name)) {
- throw x.syntaxError("Mismatched close tag");
- }
- if (x.nextToken() != GT) {
- throw x.syntaxError("Misshaped close tag");
- }
- return true;
- } else if (t instanceof Character) {
- throw x.syntaxError("Misshaped tag");
- // Open tag <
- } else {
- n = (String)t;
- t = null;
- o = new JSONObject();
- while (true) {
- if (t == null) {
- t = x.nextToken();
- }
- // attribute = value
- if (t instanceof String) {
- s = (String)t;
- t = x.nextToken();
- if (t == EQ) {
- t = x.nextToken();
- if (!(t instanceof String)) {
- throw x.syntaxError("Missing value");
- }
- o.accumulate(s, t);
- t = null;
- } else {
- o.accumulate(s, Boolean.TRUE);
- }
- // Empty tag <.../>
- } else if (t == SLASH) {
- if (x.nextToken() != GT) {
- throw x.syntaxError("Misshaped tag");
- }
- if (o.length() == 0) {
- context.accumulate(n, Boolean.TRUE);
- } else {
- context.accumulate(n, o);
- }
- return false;
- // Content, between <...> and </...>
- } else if (t == GT) {
- while (true) {
- t = x.nextContent();
- if (t == null) {
- if (name != null) {
- throw x.syntaxError("Unclosed tag " + name);
- }
- return false;
- } else if (t instanceof String) {
- s = (String)t;
- if (s.length() > 0) {
- o.accumulate("content", s);
- }
- // Nested element
- } else if (t == LT) {
- if (parse(x, o, n)) {
- if (o.length() == 0) {
- context.accumulate(n, Boolean.TRUE);
- } else if (o.length() == 1 &&
- o.opt("content") != null) {
- context.accumulate(n, o.opt("content"));
- } else {
- context.accumulate(n, o);
- }
- return false;
- }
- }
- }
- } else {
- throw x.syntaxError("Misshaped tag");
- }
- }
- }
- }
- /**
- * Convert a well-formed (but not necessarily valid) XML string into a
- * JSONObject. Some information may be lost in this transformation
- * because JSON is a data format and XML is a document format. XML uses
- * elements, attributes, and content text, while JSON uses unordered
- * collections of name/value pairs and arrays of values. JSON does not
- * does not like to distinguish between elements and attributes.
- * Sequences of similar elements are represented as JSONArrays. Content
- * text may be placed in a "content" member. Comments, prologs, DTDs, and
- * <code><[ [ ]]></code> are ignored.
- * @param string The source string.
- * @return A JSONObject containing the structured data from the XML string.
- * @throws ParseException
- */
- public static JSONObject toJSONObject(String string) throws ParseException {
- JSONObject o = new JSONObject();
- XMLTokener x = new XMLTokener(string);
- while (x.more()) {
- x.skipPast("<");
- parse(x, o, null);
- }
- return o;
- }
- /**
- * Convert a JSONObject into a well-formed XML string.
- * @param o A JSONObject.
- * @return A string.
- */
- public static String toString(Object o) {
- return toString(o, null);
- }
- /**
- * Convert a JSONObject into a well-formed XML string.
- * @param o A JSONObject.
- * @param tagName The optional name of the enclosing tag.
- * @return A string.
- */
- public static String toString(Object o, String tagName) {
- StringBuffer a = null; // attributes, inside the <...>
- StringBuffer b = new StringBuffer(); // body, between <...> and </...>
- int i;
- JSONArray ja;
- JSONObject jo;
- String k;
- Iterator keys;
- int len;
- String s;
- Object v;
- if (o instanceof JSONObject) {
- // Emit <tagName
- if (tagName != null) {
- a = new StringBuffer();
- a.append('<');
- a.append(tagName);
- }
- // Loop thru the keys. Some keys will produce attribute material, others
- // body material.
- jo = (JSONObject)o;
- keys = jo.keys();
- while (keys.hasNext()) {
- k = keys.next().toString();
- v = jo.get(k);
- if (v instanceof String) {
- s = (String)v;
- } else {
- s = null;
- }
- // Emit a new tag <k... in body
- if (tagName == null || v instanceof JSONObject ||
- (s != null && k != "content" && (s.length() > 60 ||
- (s.indexOf('"') >= 0 && s.indexOf(''') >= 0)))) {
- b.append(toString(v, k));
- // Emit content in body
- } else if (k.equals("content")) {
- b.append(escape(v.toString()));
- // Emit an array of similar keys in body
- } else if (v instanceof JSONArray) {
- ja = (JSONArray)v;
- len = ja.length();
- for (i = 0; i < len; i += 1) {
- b.append(toString(ja.get(i), k));
- }
- // Emit an attribute
- } else {
- a.append(' ');
- a.append(k);
- a.append('=');
- a.append(toString(v));
- }
- }
- if (tagName != null) {
- // Close an empty element
- if (b.length() == 0) {
- a.append("/>");
- } else {
- // Close the start tag and emit the body and the close tag
- a.append('>');
- a.append(b);
- a.append("</");
- a.append(tagName);
- a.append('>');
- }
- return a.toString();
- }
- return b.toString();
- // XML does not have good support for arrays. If an array appears in a place
- // where XML is lacking, synthesize an <array> element.
- } else if (o instanceof JSONArray) {
- ja = (JSONArray)o;
- len = ja.length();
- for (i = 0; i < len; ++i) {
- b.append(toString(
- ja.opt(i), (tagName == null) ? "array" : tagName));
- }
- return b.toString();
- } else {
- s = (o == null) ? "null" : escape(o.toString());
- return (tagName == null) ?
- """ + s + """ :
- "<" + tagName + ">" + s + "</" + tagName + ">";
- }
- }
- }