/* XMLs.java Purpose: Description: History: 91/01/07 17:36:07, Create, Tom M. Yeh Copyright (C) 2001 Potix Corporation. All Rights Reserved. {{IS_RIGHT This program is distributed under LGPL Version 2.1 in the hope that it will be useful, but WITHOUT ANY WARRANTY. }}IS_RIGHT */ package org.zkoss.xml; import org.zkoss.idom.Verifier; /** * The XML relevant utilities. * * @author tomyeh * @see org.zkoss.idom.Element */ public class XMLs { /** Converting a name to a valid XML name. * Note: it is not reversible. */ public static final String toXMLName(String name) { if (name == null || name.length() == 0) return "_"; StringBuffer sb = null; for (int j = 0, len = name.length(); j < len; ++j) { final char cc = name.charAt(j); if ((j == 0 && !Verifier.isXMLNameStartCharacter(cc)) || cc == ':' || !Verifier.isXMLNameCharacter(cc)) { if (sb == null) { sb = new StringBuffer(len + 8); if (j > 0) sb.append(name.substring(0, j)); } sb.append('_').append(Integer.toHexString(cc)); } else if (sb != null) { sb.append(cc); } } return sb != null ? sb.toString(): name; } /** Encodes a value such that it could be used as XML attribute. */ public static final String encodeAttribute(String value) { StringBuffer sb = null; for (int j = 0, len = value.length(); j < len; ++j) { final char cc = value.charAt(j); final String rep; switch (cc) { case '"': rep = """; break; case '&': rep = "&"; break; default: if (sb != null) sb.append(cc); continue; } if (sb == null) { sb = new StringBuffer(len + 8); if (j > 0) sb.append(value.substring(0, j)); } sb.append(rep); } return sb != null ? sb.toString(): value; } /** Encodes a value such that it could be enclosed by an XML element. * * <p>Note: It is sometime improper to use CDATA if the text contains * CDATA, too. The simplest way is NOT to use CDATA but encoding * the string by this method. */ public static final String encodeText(String value) { StringBuffer sb = null; for (int j = 0, len = value.length(); j < len; ++j) { final char cc = value.charAt(j); final String rep; switch (cc) { case '<': rep = "<"; break; case '>': rep = ">"; break; case '&': rep = "&"; break; case '"': rep = """; break; default: if (sb != null) sb.append(cc); continue; } if (sb == null) { sb = new StringBuffer(len + 8); if (j > 0) sb.append(value.substring(0, j)); } sb.append(rep); } return sb != null ? sb.toString(): value; } /** Encodes a value and appends it to a string buffer, * such that it could be enclosed by an XML element. * * <p>Note: It is sometime improper to use CDATA if the text contains * CDATA, too. The simplest way is NOT to use CDATA but encoding * the string by this method. */ public static final StringBuffer encodeText(StringBuffer sb, String value) { int len = value.length(); if (sb == null) sb = new StringBuffer(len); for (int j = 0; j < len; ++j) { final char cc = value.charAt(j); final String rep; switch (cc) { case '<': sb.append("<"); break; case '>': sb.append(">"); break; case '&': sb.append("&"); break; case '"': sb.append("""); break; default: sb.append(cc); break; } } return sb; } /** Encodes a value of the specified range, * and appends it to a string buffer, * such that it could be enclosed by an XML element. * * <p>Note: It is sometime improper to use CDATA if the text contains * CDATA, too. The simplest way is NOT to use CDATA but encoding * the string by this method. * * @param value the string to encode * @param begin the beginning index, inclusive of the string to encode (i.e., value), included * @param end the ending index, exclusive of the string to encode (i.e., value), excluded * @since 5.0.0 */ public static final StringBuffer encodeText(StringBuffer sb, String value, int begin, int end) { if (end > value.length()) end = value.length(); if (sb == null) sb = new StringBuffer(end - begin + 8); for (int j = begin; j < end; ++j) { final char cc = value.charAt(j); final String rep; switch (cc) { case '<': sb.append("<"); break; case '>': sb.append(">"); break; case '&': sb.append("&"); break; case '"': sb.append("""); break; default: sb.append(cc); break; } } return sb; } /** Encodes a string that special characters are quoted to be compatible * with HTML/XML. * For example, < is translated to &lt;. * * & -> &amp;<br/> * < -> &lt;<br/> * > -> &gt;<br/> * " -> &#034;<br/> * ' -> &#039;<br/> * * @param s the string to quote; null is OK * @return the escaped string, or an empty string if s is null */ public static final String escapeXML(String s) { if (s == null) return ""; final StringBuffer sb = new StringBuffer(s.length() + 16); for (int j = 0, len = s.length(); j < len; ++j) { final char cc = s.charAt(j); final String esc = escapeXML(cc); if (esc != null) sb.append(esc); else sb.append(cc); } return s.length() == sb.length() ? s: sb.toString(); } /** Escapes a character into a string if it is a special XML character, * returns null if not a special character. * * & -> &amp;<br/> * < -> &lt;<br/> * > -> &gt;<br/> * " -> &#034;<br/> * ' -> &#039;<br/> */ public static final String escapeXML(char cc) { switch (cc) { case '"': return """; case '\'': return "'"; case '>': return ">"; case '<': return "<"; case '&': return "&"; } return null; }}