⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlutil.java

📁 利用SyncML开发客户端程序的中间件
💻 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 + -