📄 xmlutil.java
字号:
/*
* Copyright (C) 2006-2007 Funambol
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.funambol.util;
import java.util.Vector;
import java.util.Hashtable;
/**
* Utility class that XML manipulation functions.
*/
public class XmlUtil {
// This class cannot be instantiated
private XmlUtil() {
}
/**
* <p>Escapes the characters in a <code>String</code> using XML entities.</p>
*
*
* <p>Supports only the four basic XML entities (gt, lt, quot, amp).
* Does not support DTDs or external entities.</p>
*
* @param str the <code>String</code> to escape, may be null
* @return a new escaped <code>String</code>, <code>null</code> if null string input
*/
public static String escapeXml(String str) {
if (str == null) {
return null;
}
return Entities.XML.escape(str);
}
/**
* <p>Unescapes a string containing XML entity escapes to a string
* containing the actual Unicode characters corresponding to the
* escapes.</p>
*
* <p>Supports only the four basic XML entities (gt, lt, quot, amp).
* Does not support DTDs or external entities.</p>
*
* @param str the <code>String</code> to unescape, may be null
* @return a new unescaped <code>String</code>, <code>null</code> if null string input
*/
public static String unescapeXml(String str) {
if (str == null) {
return null;
}
return Entities.XML.unescape(str);
}
/**
* Return the index of <i>tag</i>, validating also the presence
* of the end tag.
*
* @param xml xml msg
* @param tag tag to find
* @return tag index
*/
public static int getTag(ChunkedString xml, String tag) {
String startTag = null;
String endTag = null;
int ret = -1;
startTag = "<" + tag + ">";
endTag = "</" + tag + ">";
// Try <tag>...</tag>
ret = xml.indexOf(startTag);
if ( (ret != -1) && xml.indexOf(endTag, ret) != -1 ) {
return ret; // Tag without attributes found
}
// Try <tag attr="xxx">...</tag>
startTag = "<" + tag + " ";
ret = xml.indexOf(startTag);
if ( (ret != -1) && xml.indexOf(endTag, ret) != -1 ) {
return ret; // Tag with attributes found
}
// Try <tag/>
if( (ret = xml.indexOf("<" + tag + "/>")) != -1 ) {
return ret; // Empty tag found
}
// tag not found
return -1;
}
public static Hashtable getTagAttributes(ChunkedString xml, String tag) {
String startTag = null;
String endTag = null;
int tagPos = 0, endPos = 0;
Hashtable ret = new Hashtable();
// Try <tag attr="xxx">...</tag>
startTag = "<" + tag + " ";
tagPos = xml.indexOf(startTag);
endPos = xml.indexOf(">", tagPos);
if ( (tagPos != -1) && (endPos != -1) ) {
int space = xml.indexOf(" ");
if(space != -1) {
ChunkedString[] attrlist = xml.substring(space, endPos).split(",");
for(int i=0, l=attrlist.length; i<l; i++) {
// TODO: find only the first '=', not with split but with indexOf.
ChunkedString[] attr = attrlist[i].split("=");
if(attr.length > 1) {
String val = StringUtil.trim(attr[1].toString().trim(), '\"');
ret.put(attr[0].toString().trim(), val);
}
}
}
}
return ret;
}
/**
* Make a String by value of <i>tag</i>.
*
* @param xml xml msg
* @param tag tag to find + sourceType +
* @return tag value
*/
public static ChunkedString getTagValue(ChunkedString xml, String tag)
throws XmlException {
String startTag = "<" + tag + ">";
String endTag = "</" + tag + ">";
//Log.info(xml.toString());
try {
// Find start tag
int stidx = xml.indexOf(startTag);
if(stidx == -1) {
// Try with namespace or attributes
startTag = "<" + tag + " ";
stidx = xml.indexOf(startTag);
if (stidx == -1) {
throw new XmlException("getTagValue: can't find tag: " + tag);
}
else {
// Find closing '>' for tag with attr or namespace
stidx = xml.indexOf(">", stidx);
if (stidx == -1) {
throw new XmlException("getTagValue: unclosed tag: " + tag);
}
stidx++; // Skip the '>'
}
}
else {
// Point to the end of the tag
stidx += startTag.length();
}
// Find end tag
int endidx = xml.indexOf(endTag, stidx);
if(endidx == -1) {
throw new XmlException("getTagValue: can't find tag end: " + tag);
}
// Get the tag content
return xml.substring(stidx, endidx);
}
catch (StringIndexOutOfBoundsException e){
// should not happen anymore.
Log.error("StringIndexOutofBound in getTagValue");
throw new XmlException("Error parsing xml, tag: " + tag);
}
}
/**
* Return a Vector of String with tags matching the search tag.
*
* @param xmlInput Vector of XML tags to search in
* @param tag to find
* @return found tags (empty if no one found)
*/
public static Vector getTagValues(Vector xmlInput, String tag)
throws XmlException {
Vector xmlReturn = new Vector();
String plainTag = "<" + tag + ">" ;
String attrTag = "<" + tag + " " ;
String endTag = "</" + tag + ">" ;
int endIdx = 0;
for (int j=0, l = xmlInput.size(); j < l; j++) {
ChunkedString xmlInputTag = (ChunkedString) xmlInput.elementAt(j);
//
// tag without namespace
// or tag with namespace
//
while (xmlInputTag.indexOf(plainTag) != -1 ||
xmlInputTag.indexOf(attrTag) != -1) {
xmlReturn.addElement(getTagValue(xmlInputTag, tag));
endIdx = xmlInputTag.indexOf(endTag) + endTag.length();
if (endIdx == -1) {
Log.error("getTagValues: can't find '" + endTag + "'");
throw new XmlException("getTagValues: parse exception.");
}
xmlInputTag = xmlInputTag.substring(endIdx);
}
}
return xmlReturn;
}
/**
* Return a Vector of String with tags matching the search tag.
*
* @param xmlInput XML document to search in
* @param tag to find
* @return find tags
*/
public static Vector getTagValues(ChunkedString xmlInput, String tag)
throws XmlException {
Vector tmp = new Vector(1);
tmp.addElement(xmlInput);
return getTagValues(tmp, tag);
}
/**
* Add an empty tag to the StringBuffer out.
*
* @param out the buffer to append to
* @param tag tag to be appended
*/
public static void addElement(StringBuffer out, String tag) {
out.append("<").append(tag).append("/>");
}
/**
* Add an empty tag to the StringBuffer out.
*
* @param out the buffer to append to
* @param tag tag to be appended
*/
public static void addElement(StringBuffer out, String tag, String content) {
out.append("<").append(tag).append(">").
append(content).
append("</").append(tag).append(">");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -