001: /* XMLs.java
002:
003: {{IS_NOTE
004:
005: Purpose:
006: Description:
007: History:
008: 91/01/07 17:36:07, Create, Tom M. Yeh
009: }}IS_NOTE
010:
011: Copyright (C) 2001 Potix Corporation. All Rights Reserved.
012:
013: {{IS_RIGHT
014: This program is distributed under GPL Version 2.0 in the hope that
015: it will be useful, but WITHOUT ANY WARRANTY.
016: }}IS_RIGHT
017: */
018: package org.zkoss.xml;
019:
020: import org.zkoss.idom.Verifier;
021:
022: /**
023: * The XML relevant utilities.
024: *
025: * @author tomyeh
026: * @see org.zkoss.idom.Element
027: */
028: public class XMLs {
029: /** Converting a name to a valid XML name.
030: * Note: it is not reversible.
031: */
032: public static final String toXMLName(String name) {
033: if (name == null || name.length() == 0)
034: return "_";
035:
036: StringBuffer sb = null;
037: for (int j = 0, len = name.length(); j < len; ++j) {
038: final char cc = name.charAt(j);
039: if ((j == 0 && !Verifier.isXMLNameStartCharacter(cc))
040: || cc == ':' || !Verifier.isXMLNameCharacter(cc)) {
041: if (sb == null) {
042: sb = new StringBuffer(len + 8);
043: if (j > 0)
044: sb.append(name.substring(0, j));
045: }
046: sb.append('_').append(Integer.toHexString(cc));
047: } else if (sb != null) {
048: sb.append(cc);
049: }
050: }
051: return sb != null ? sb.toString() : name;
052: }
053:
054: /** Encodes a value such that it could be used as XML attribute.
055: */
056: public static final String encodeAttribute(String value) {
057: StringBuffer sb = null;
058: for (int j = 0, len = value.length(); j < len; ++j) {
059: final char cc = value.charAt(j);
060: final String rep;
061: switch (cc) {
062: case '"':
063: rep = """;
064: break;
065: case '&':
066: rep = "&";
067: break;
068: default:
069: if (sb != null)
070: sb.append(cc);
071: continue;
072: }
073:
074: if (sb == null) {
075: sb = new StringBuffer(len + 8);
076: if (j > 0)
077: sb.append(value.substring(0, j));
078: }
079: sb.append(rep);
080: }
081: return sb != null ? sb.toString() : value;
082: }
083:
084: /** Encodes a value such that it could be enclosed by a XML elemnt.
085: *
086: * <p>Note: It is sometime inproper to use CDATA if the text contains
087: * CDATA, too. The simplest way is NOT to use CDATA but encoding
088: * the string by this method.
089: */
090: public static final String encodeText(String value) {
091: StringBuffer sb = null;
092: for (int j = 0, len = value.length(); j < len; ++j) {
093: final char cc = value.charAt(j);
094: final String rep;
095: switch (cc) {
096: case '<':
097: rep = "<";
098: break;
099: case '>':
100: rep = ">";
101: break;
102: case '&':
103: rep = "&";
104: break;
105: case '"':
106: rep = """;
107: break;
108: default:
109: if (sb != null)
110: sb.append(cc);
111: continue;
112: }
113:
114: if (sb == null) {
115: sb = new StringBuffer(len + 8);
116: if (j > 0)
117: sb.append(value.substring(0, j));
118: }
119: sb.append(rep);
120: }
121: return sb != null ? sb.toString() : value;
122: }
123:
124: /** Encodes a value and appends it to a string buffer,
125: * such that it could be enclosed by a XML elemnt.
126: *
127: * <p>Note: It is sometime inproper to use CDATA if the text contains
128: * CDATA, too. The simplest way is NOT to use CDATA but encoding
129: * the string by this method.
130: */
131: public static final StringBuffer encodeText(StringBuffer sb,
132: String value) {
133: if (sb == null)
134: sb = new StringBuffer(value.length());
135: for (int j = 0, len = value.length(); j < len; ++j) {
136: final char cc = value.charAt(j);
137: final String rep;
138: switch (cc) {
139: case '<':
140: sb.append("<");
141: break;
142: case '>':
143: sb.append(">");
144: break;
145: case '&':
146: sb.append("&");
147: break;
148: case '"':
149: sb.append(""");
150: break;
151: default:
152: sb.append(cc);
153: break;
154: }
155: }
156: return sb;
157: }
158:
159: /** Encodes a string that special characters are quoted to be compatible
160: * with HTML/XML.
161: * For example, < is translated to &lt;.
162: *
163: * & -> &amp;<br/>
164: * < -> &lt;<br/>
165: * > -> &gt;<br/>
166: * " -> &#034;<br/>
167: * ' -> &#039;<br/>
168: *
169: * @param s the string to quote; null is OK
170: * @return the escaped string, or an empty string if s is null
171: */
172: public static final String escapeXML(String s) {
173: if (s == null)
174: return "";
175: final StringBuffer sb = new StringBuffer(s.length() + 16);
176: for (int j = 0, len = s.length(); j < len; ++j) {
177: final char cc = s.charAt(j);
178: final String esc = escapeXML(cc);
179: if (esc != null)
180: sb.append(esc);
181: else
182: sb.append(cc);
183: }
184: return s.length() == sb.length() ? s : sb.toString();
185: }
186:
187: /** Enscapes a character into a string if it is a special XML character,
188: * returns null if not a special character.
189: *
190: * & -> &amp;<br/>
191: * < -> &lt;<br/>
192: * > -> &gt;<br/>
193: * " -> &#034;<br/>
194: * ' -> &#039;<br/>
195: */
196: public static final String escapeXML(char cc) {
197: switch (cc) {
198: case '"':
199: return """;
200: case '\'':
201: return "'";
202: case '>':
203: return ">";
204: case '<':
205: return "<";
206: case '&':
207: return "&";
208: }
209: return null;
210: }
211: }
|