/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is TransforMiiX XSLT processor. * * The Initial Developer of the Original Code is The MITRE Corporation. * Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation. * * Portions created by Keith Visco as a Non MITRE employee, * (C) 1999 Keith Visco. All Rights Reserved. * * Contributor(s): * Keith Visco, kvisco@ziplink.net * -- original author. * Lidong, lidong520@263.net * -- unicode bug fix * * $Id: XMLUtils.cpp,v 1.3 2000-03-23 10:17:14 kvisco%ziplink.net Exp $ */ /** * An XML utility class * @author Keith Visco **/ #include "XMLUtils.h" //------------------------------/ //- Implementation of XMLUtils -/ //------------------------------/ const String XMLUtils::XMLNS = "xmlns"; void XMLUtils::getNameSpace(const String& src, String& dest) { //-- anything preceding ':' is the namespace part of the name int idx = src.indexOf(':'); if ( idx > 0 ) { //-- create new String to prevent any chars in dest from being //-- lost String tmp; src.subString(0,idx, tmp); dest.append(tmp); } else dest.append(""); } //-- getNameSpace void XMLUtils::getLocalPart(const String& src, String& dest) { //-- anything after ':' is the local part of the name int idx = src.indexOf(':'); if ( idx < -1 ) idx = -1; //-- create new String to prevent any chars in dest from being //-- lost String tmp; src.subString(idx+1, tmp); dest.append(tmp); } //-- getLocalPart /** * Returns true if the given character represents an Alpha letter **/ MBool XMLUtils::isAlphaChar(Int32 ch) { if ((ch >= 'a' ) && (ch <= 'z' )) return MB_TRUE; if ((ch >= 'A' ) && (ch <= 'Z' )) return MB_TRUE; return MB_FALSE; } //-- isAlphaChar /** * Returns true if the given character represents a numeric letter (digit) **/ MBool XMLUtils::isDigit(Int32 ch) { if ((ch >= '0') && (ch <= '9')) return MB_TRUE; return MB_FALSE; } //-- isDigit /** * Returns true if the given character is an allowable QName character **/ MBool XMLUtils::isNCNameChar(Int32 ch) { if (isDigit(ch) || isAlphaChar(ch)) return MB_TRUE; return (MBool) ((ch == '.') ||(ch == '_') || (ch == '-')); } //-- isNCNameChar /** * Returns true if the given character is an allowable NCName character **/ MBool XMLUtils::isQNameChar(Int32 ch) { return (MBool) (( ch == ':') || isNCNameChar(ch)); } //-- isQNameChar /** * Returns true if the given String is a valid XML QName **/ MBool XMLUtils::isValidQName(String& name) { int size = name.length(); if ( size == 0 ) return MB_FALSE; else if ( !isAlphaChar(name.charAt(0))) return MB_FALSE; else { for ( int i = 1; i < size; i++) { if ( ! isQNameChar(name.charAt(i))) return MB_FALSE; } } return MB_TRUE; } //-- isValidQName /** * Returns true if the given string has only whitespace characters **/ MBool XMLUtils::isWhitespace(const String& text) { for ( int i = 0; i < text.length(); i++ ) { Int32 ch = text.charAt(i); switch ( ch ) { case ' ' : case '\n' : case '\r' : case '\t' : break; default: return MB_FALSE; } } return MB_TRUE; } //-- isWhitespace /** * Normalizes the value of an XML attribute **/ void XMLUtils::normalizeAttributeValue(String& attValue) { Int32 size = attValue.length(); //-- make copy of chars UNICODE_CHAR* chars = new UNICODE_CHAR[size]; attValue.toUnicode(chars); //-- clear attValue attValue.clear(); Int32 cc = 0; MBool addSpace = MB_FALSE; while ( cc < size) { UNICODE_CHAR ch = chars[cc++]; switch (ch) { case ' ': if ( attValue.length() > 0) addSpace = MB_TRUE; break; case '\r': break; case '\n': attValue.append(" "); break; case '\'': attValue.append("'"); break; case '\"': attValue.append("""); break; default: if ( addSpace) { attValue.append(' '); addSpace = MB_FALSE; } attValue.append(ch); break; } } delete chars; } //-- normalizeAttributeValue /** * Normalizes the value of a XML processing instruction **/ void XMLUtils::normalizePIValue(String& piValue) { Int32 size = piValue.length(); //-- make copy of chars UNICODE_CHAR* chars = new UNICODE_CHAR[size]; piValue.toUnicode(chars); //-- clear attValue piValue.clear(); Int32 cc = 0; UNICODE_CHAR prevCh = 0x0000; while ( cc < size) { UNICODE_CHAR ch = chars[cc++]; switch (ch) { case '>': if ( prevCh == '?' ) { piValue.append(' '); } piValue.append(ch); break; default: piValue.append(ch); break; } prevCh = ch; } delete chars; } //-- noramlizePIValue /** * Strips whitespace from the given String. * Newlines (#xD), tabs (#x9), and consecutive spaces (#x20) are * converted to a single space (#x20). * @param data the String to strip whitespace from * @param dest the destination String to append the result to **/ void XMLUtils::stripSpace (const String& data, String& dest) { stripSpace(data,dest,MB_FALSE,MB_FALSE); } //-- stripSpace /** * Strips whitespace from the given String. * Newlines (#xD), tabs (#x9), and consecutive spaces (#x20) are * converted to a single space (#x20). * @param data the String to strip whitespace from * @param dest the destination String to append the result to * @param stripAllLeadSpace, a boolean indicating whether or not to * strip all leading space. If true all whitespace from the start of the * given String will be stripped. If false, all whitespace from the start * of the given String will be converted to a single space. * @param stripAllTrailSpace, a boolean indicating whether or not to * strip all trailing space. If true all whitespace at the end of the * given String will be stripped. If false, all whitespace at the end * of the given String will be converted to a single space. **/ void XMLUtils::stripSpace ( const String& data, String& dest, MBool stripAllLeadSpace, MBool stripAllTrailSpace ) { UNICODE_CHAR lastToken, token; lastToken = 0x0000; Int32 len = data.length(); Int32 oldLen = dest.length(); // indicates we have seen at least one // non whitespace charater MBool validChar = MB_FALSE; for (Int32 i = 0; i < len; i++) { token = data.charAt(i); switch(token) { case 0x0020: // space case 0x0009: // tab case 0x000A: // LF case 0x000D: // CR token = 0x0020; if (stripAllLeadSpace && (!validChar)) break; if (lastToken != token) dest.append(token); break; default: dest.append(token); validChar = MB_TRUE; break; } lastToken = token; } //-- remove last trailing space if necessary if (stripAllTrailSpace) { len = dest.length(); if ( (len > oldLen) && (dest.charAt(len-1) == 0x0020) ) dest.setLength(len-1); } } //-- stripSpace