$v) $val[$k] = self::raw2htmlname($v);
			return $val;
		} else {
			return preg_replace('/[^a-zA-Z0-9\-_:.]+/','', $val);
		}
	}
	
	/**
	 * Ensure that text is properly escaped for XML.
	 * 
	 * @see http://www.w3.org/TR/REC-xml/#dt-escape
	 * @param array|string $val String to escape, or array of strings
	 * @return array|string
	 */
	public static function raw2xml($val) {
		if(is_array($val)) {
			foreach($val as $k => $v) $val[$k] = self::raw2xml($v);
			return $val;
		} else {
			return htmlspecialchars($val, ENT_QUOTES, 'UTF-8');
		}
	}
	
	/**
	 * Ensure that text is properly escaped for Javascript.
	 *
	 * @param array|string $val String to escape, or array of strings
	 * @return array|string
	 */
	public static function raw2js($val) {
		if(is_array($val)) {
			foreach($val as $k => $v) $val[$k] = self::raw2js($v);
			return $val;
		} else {
			return str_replace(
				// Intercepts some characters such as <, >, and & which can interfere
				array("\\", '"', "\n", "\r", "'", "<", ">", "&"),
				array("\\\\", '\"', '\n', '\r', "\\'", "\\x3c", "\\x3e", "\\x26"),
				$val
			);
		}
	}
	/**
	 * Encode a value as a JSON encoded string.
	 *
	 * @param mixed $val Value to be encoded
	 * @return string JSON encoded string
	 */
	public static function raw2json($val) {
		return json_encode($val);
	}
	/**
	 * Encode an array as a JSON encoded string.
	 * THis is an alias to {@link raw2json()}
	 *
	 * @param array $val Array to convert
	 * @return string JSON encoded string
	 */
	public static function array2json($val) {
		return self::raw2json($val);
	}
	public static function raw2sql($val) {
		if(is_array($val)) {
			foreach($val as $k => $v) $val[$k] = self::raw2sql($v);
			return $val;
		} else {
			return DB::getConn()->addslashes($val);
		}
	}
	/**
	 * Convert XML to raw text.
	 * @uses html2raw()
	 * @todo Currently xx; entries are stripped; they should be converted
	 */
	public static function xml2raw($val) {
		if(is_array($val)) {
			foreach($val as $k => $v) $val[$k] = self::xml2raw($v);
			return $val;
		} else {
			// More complex text needs to use html2raw instead
			if(strpos($val,'<') !== false) return self::html2raw($val);
			else return html_entity_decode($val, ENT_QUOTES, 'UTF-8');
		}
	}
	/**
	 * Convert a JSON encoded string into an object.
	 *
	 * @param string $val
	 * @return object|boolean
	 */
	public static function json2obj($val) {
		return json_decode($val);
	}
	/**
	 * Convert a JSON string into an array.
	 * 
	 * @uses json2obj
	 * @param string $val JSON string to convert
	 * @return array|boolean
	 */
	public static function json2array($val) {
		return json_decode($val, true);
	}
	
	/**
 * Converts an XML string to a PHP array
 * See http://phpsecurity.readthedocs.org/en/latest/Injection-Attacks.html#xml-external-entity-injection
 *
 * @uses recursiveXMLToArray()
 * @param string $val
 * @param boolean $disableDoctypes Disables the use of DOCTYPE, and will trigger an error if encountered.
 * false by default.
 * @param boolean $disableExternals Disables the loading of external entities. false by default.
 * @return array
 */
    public static function xml2array($val, $disableDoctypes = false, $disableExternals = false) {
        // Check doctype
        if($disableDoctypes && preg_match('/\<\!DOCTYPE.+]\>/', $val)) {
            throw new InvalidArgumentException('XML Doctype parsing disabled');
        }
        // Disable external entity loading
        if($disableExternals) $oldVal = libxml_disable_entity_loader($disableExternals);
        try {
            $xml = new SimpleXMLElement($val);
            $result = self::recursiveXMLToArray($xml);
        } catch(Exception $ex) {
            if($disableExternals) libxml_disable_entity_loader($oldVal);
            throw $ex;
        }
        if($disableExternals) libxml_disable_entity_loader($oldVal);
        return $result;
    }
    /**
     * Convert a XML string to a PHP array recursively. Do not
     * call this function directly, Please use {@link Convert::xml2array()}
     *
     * @param SimpleXMLElement
     *
     * @return mixed
     */
    protected static function recursiveXMLToArray($xml) {
        if(is_object($xml) && get_class($xml) == 'SimpleXMLElement') {
            $attributes = $xml->attributes();
            foreach($attributes as $k => $v) {
                if($v) $a[$k] = (string) $v;
            }
            $x = $xml;
            $xml = get_object_vars($xml);
        }
        if(is_array($xml)) {
            if(count($xml) == 0) return (string) $x; // for CDATA
            foreach($xml as $key => $value) {
                $r[$key] = self::recursiveXMLToArray($value);
            }
            if(isset($a)) $r['@'] = $a; // Attributes
            return $r;
        }
        return (string) $xml;
    }
	
	/**
	 * Create a link if the string is a valid URL
	 *
	 * @param string The string to linkify
	 * @return A link to the URL if string is a URL
	 */
	public static function linkIfMatch($string) {
		if( preg_match( '/^[a-z+]+\:\/\/[a-zA-Z0-9$-_.+?&=!*\'()%]+$/', $string ) )
			return "$string";
		else
			return $string;
	}
	
	/**
	 * Simple conversion of HTML to plaintext.
	 * 
	 * @param $data string
	 * @param $preserveLinks boolean
	 * @param $wordwrap array 
	 */
	public static function html2raw($data, $preserveLinks = false, $wordWrap = 60, $config = null) {
		$defaultConfig = array(
			'PreserveLinks' => false,
			'ReplaceBoldAsterisk' => true,
			'CompressWhitespace' => true,
			'ReplaceImagesWithAlt' => true,
		);
		if(isset($config)) {
			$config = array_merge($defaultConfig,$config);
		} else {
			$config = $defaultConfig;
		}
		$data = preg_replace("/