信大家都用过Kxml的东西了,不过个人感觉kxml还是大了些。现在介绍一个比kxml跟简介的xml的类。对于一些小项目,或者对xml解释要求不是很高的项目来说却是个不错的选择。
下面看看那代码与Demo吧。
Java代码
package org.gggeye.easymf.xml;
import java.util.Enumeration;
import java.util.Vector;
/**
*
* @author wuhua
* <a href=" http://wuhua.3geye.net">我的博客</a>
*
*/
public class XMLParser {
private XMLNode root=null;
private XMLNode exeNode=null;
private int offset=0;
private String xml="";
private int xmlLength=0;
private String version="1.1";
private String encoding="UTF-8";
public XMLParser(String xml){
this.xml=xml;
this.xmlLength=xml.length();
}
public char getNextCharacter(){
char rt= xml.charAt(offset);
offset++;
return rt;
}
/** *//**
* 判断下一字符是否为指定字符token
* @param token
* @return
*/
private boolean match(char token){
for(int i=offset;i<this.xmlLength;i++){
char tc=xml.charAt(i);
if (tc!=' '){
if (tc==token){
return true;
}else{
return false;
}
}
}
return false;
}
private String getDescription(){
skipSpace();
StringBuffer desc=new StringBuffer();
while(offset<this.xmlLength-2){
char tc1=this.getNextCharacter();
if (tc1=='-'){
if ((xml.charAt(offset)=='-')&&(xml.charAt(offset+1)=='>')){
offset+=2;
return desc.toString();
}
}else{
desc.append(tc1);
}
}
return null;
}
/** *//**
* 获取Node名称
* @return
*/
private String getNodeName(){
skipSpace();
char[] name=new char[120];//
int i=0;
while(i<120){
char tc=getNextCharacter();
if ((tc==' ')||(tc=='>')||(tc=='/')){
if (i>0)
return new String(name).trim();
}else {
name[i]=tc;
i++;
if (i>120){
System.err.println("NODE NAME长度只能小于120");
return null;
}
}
}
return null;
}
/** *//**
* 获取属性信息
*
*/
private void getAttributes(){
skipSpace();
StringBuffer name=new StringBuffer();
StringBuffer value=new StringBuffer();
boolean isAttribute=false;
while(offset<this.xmlLength){
char tc1=this.getNextCharacter();
if (tc1=='='){
skipSpace();
char tc2=this.getNextCharacter();
if (tc2=='"'){//获取属性值
isAttribute=true;
while(offset<this.xmlLength){
char tc3=this.getNextCharacter();
if (tc3=='"'){
this.exeNode.setAttribute(name.toString(),value.toString());
this.skipSpace();
value.delete(0,value.length());
name.delete(0,name.length());
break;
}else
value.append(tc3);
}
}
}else if (tc1=='/'){
skipSpace();
char tc2=this.getNextCharacter();
if (tc2!='>'){
System.err.println("/必须使用>来封闭");
}else{
this.exeNode=this.exeNode.getParent();
break;
}
}else if (tc1=='>'){
break;
}else{
name.append(tc1);
}
}
}
private int skipSpace(){
int skipCount=0;
while(offset<xml.length()){
char tc=xml.charAt(offset);
if ((tc!=' ')&&(tc!=' ')&&(tc!=' ')){
return skipCount;
}else{
offset++;
skipCount++;
}
}
return skipCount;
}
private String getValue(){
StringBuffer value=new StringBuffer();
value.append(xml.charAt(offset-1));
while(offset<xml.length()){
char tc=this.getNextCharacter();
value.append(tc);
if (xml.charAt(offset)=='<'){
return value.toString().trim();
}
}
return null;
}
private void getXMLHeader(){
this.skipSpace();
if ((this.xml.charAt(offset)=='<')&&(this.xml.charAt(offset+1)=='?')){
int idx=this.xml.indexOf("version");
if (idx>0){
boolean start=false;
StringBuffer tmp=new StringBuffer();
for(int i=idx+8;i<this.xmlLength;i++){
char tc=this.xml.charAt(i);
if (tc=='"'){
if (start==false){
start=true;
}else{
break;
}
}else{
if (start)
tmp.append(tc);
}
}
this.version=tmp.toString();
}
idx=this.xml.indexOf("encoding");
if (idx>0){
boolean start=false;
StringBuffer tmp=new StringBuffer();
for(int i=idx+9;i<this.xmlLength;i++){
char tc=this.xml.charAt(i);
if (tc=='"'){
if (start==false){
start=true;
}else{
break;
}
}else{
if (start)
tmp.append(tc);
}
}
this.encoding=tmp.toString();
}
int end=this.xml.indexOf("?>");
offset=end+2;
}
}
public XMLNode parse(){
getXMLHeader();
while(offset<this.xmlLength){
this.skipSpace();
char token=getNextCharacter();
if (token=='<'){
if (match('!')){
getNextCharacter();
char tc=getNextCharacter();
if (tc=='-'){
tc=getNextCharacter();
if (tc=='-'){
//System.out.println("注释行");
String desc=getDescription();
if (this.exeNode!=null)
this.exeNode.setDescription(desc);
}else{
System.err.println("语法错误在"+offset);
return null;
}
}
}else if (match('/')){
String nodeName=this.getNodeName();
if (exeNode.getName().equalsIgnoreCase(nodeName))
exeNode=exeNode.getParent();
else{
System.err.println("期望封闭标签为:"+exeNode.getName()+",实际标签为:"+nodeName);
return null;
}
}else{
String name=this.getNodeName();
XMLNode newNode=new XMLNode(name);
if (root==null){
root=newNode;
exeNode=root;
}else{
exeNode.addChild(newNode);
exeNode=newNode;
}
char tc=this.xml.charAt(offset-1);
if (tc==' ')
getAttributes();
else{
if (tc!='>')
System.err.println(exeNode.getName()+"期待关闭");
}
}
}else{
exeNode.setValue(getValue());
}
}
return root;
}
public static void main(String[] args){
String xml="<?xml version=\"1.0\" encoding=\"GB2312\"?>" +
"<!--注释行--><root desc=\"一个测试的例子\"><book name=\"test\" " +
"value=\"我的\"/><book name=\"跌而\">我的值</book></root>";
XMLParser parser=new XMLParser(xml);
XMLNode root=parser.parse();
System.out.println(root.getName());
Vector nodes = root.getChildNodes();
load(nodes);
// System.out.println(root.toString());
}
static void load(Vector _nodes){
System.out.println(_nodes);
for(int i=0; i<_nodes.size(); i++){
XMLNode tNode = (XMLNode) _nodes.elementAt(i);
System.out.println(tNode.getName());
Enumeration keys=tNode.getAttributes().keys();
while(keys.hasMoreElements()){
String key=(String)keys.nextElement();
String value= tNode.getAttribute(key);
System.out.println(" "+ key+ "=" + value + " ");
}
System.out.println(tNode.getValue());
}
}
}
package org.gggeye.easymf.xml;
import java.util.Enumeration;
import java.util.Vector;
/**
*
* @author wuhua
* <a href=" http://wuhua.3geye.net">我的博客</a>
*
*/
public class XMLParser {
private XMLNode root=null;
private XMLNode exeNode=null;
private int offset=0;
private String xml="";
private int xmlLength=0;
private String version="1.1";
private String encoding="UTF-8";
public XMLParser(String xml){
this.xml=xml;
this.xmlLength=xml.length();
}
public char getNextCharacter(){
char rt= xml.charAt(offset);
offset++;
return rt;
}
/** *//**
* 判断下一字符是否为指定字符token
* @param token
* @return
*/
private boolean match(char token){
for(int i=offset;i<this.xmlLength;i++){
char tc=xml.charAt(i);
if (tc!=' '){
if (tc==token){
return true;
}else{
return false;
}
}
}
return false;
}
private String getDescription(){
skipSpace();
StringBuffer desc=new StringBuffer();
while(offset<this.xmlLength-2){
char tc1=this.getNextCharacter();
if (tc1=='-'){
if ((xml.charAt(offset)=='-')&&(xml.charAt(offset+1)=='>')){
offset+=2;
return desc.toString();
}
}else{
desc.append(tc1);
}
}
return null;
}
/** *//**
* 获取Node名称
* @return
*/
private String getNodeName(){
skipSpace();
char[] name=new char[120];//
int i=0;
while(i<120){
char tc=getNextCharacter();
if ((tc==' ')||(tc=='>')||(tc=='/')){
if (i>0)
return new String(name).trim();
}else {
name[i]=tc;
i++;
if (i>120){
System.err.println("NODE NAME长度只能小于120");
return null;
}
}
}
return null;
}
/** *//**
* 获取属性信息
*
*/
private void getAttributes(){
skipSpace();
StringBuffer name=new StringBuffer();
StringBuffer value=new StringBuffer();
boolean isAttribute=false;
while(offset<this.xmlLength){
char tc1=this.getNextCharacter();
if (tc1=='='){
skipSpace();
char tc2=this.getNextCharacter();
if (tc2=='"'){//获取属性值
isAttribute=true;
while(offset<this.xmlLength){
char tc3=this.getNextCharacter();
if (tc3=='"'){
this.exeNode.setAttribute(name.toString(),value.toString());
this.skipSpace();
value.delete(0,value.length());
name.delete(0,name.length());
break;
}else
value.append(tc3);
}
}
}else if (tc1=='/'){
skipSpace();
char tc2=this.getNextCharacter();
if (tc2!='>'){
System.err.println("/必须使用>来封闭");
}else{
this.exeNode=this.exeNode.getParent();
break;
}
}else if (tc1=='>'){
break;
}else{
name.append(tc1);
}
}
}
private int skipSpace(){
int skipCount=0;
while(offset<xml.length()){
char tc=xml.charAt(offset);
if ((tc!=' ')&&(tc!=' ')&&(tc!=' ')){
return skipCount;
}else{
offset++;
skipCount++;
}
}
return skipCount;
}
private String getValue(){
StringBuffer value=new StringBuffer();
value.append(xml.charAt(offset-1));
while(offset<xml.length()){
char tc=this.getNextCharacter();
value.append(tc);
if (xml.charAt(offset)=='<'){
return value.toString().trim();
}
}
return null;
}
private void getXMLHeader(){
this.skipSpace();
if ((this.xml.charAt(offset)=='<')&&(this.xml.charAt(offset+1)=='?')){
int idx=this.xml.indexOf("version");
if (idx>0){
boolean start=false;
StringBuffer tmp=new StringBuffer();
for(int i=idx+8;i<this.xmlLength;i++){
char tc=this.xml.charAt(i);
if (tc=='"'){
if (start==false){
start=true;
}else{
break;
}
}else{
if (start)
tmp.append(tc);
}
}
this.version=tmp.toString();
}
idx=this.xml.indexOf("encoding");
if (idx>0){
boolean start=false;
StringBuffer tmp=new StringBuffer();
for(int i=idx+9;i<this.xmlLength;i++){
char tc=this.xml.charAt(i);
if (tc=='"'){
if (start==false){
start=true;
}else{
break;
}
}else{
if (start)
tmp.append(tc);
}
}
this.encoding=tmp.toString();
}
int end=this.xml.indexOf("?>");
offset=end+2;
}
}
public XMLNode parse(){
getXMLHeader();
while(offset<this.xmlLength){
this.skipSpace();
char token=getNextCharacter();
if (token=='<'){
if (match('!')){
getNextCharacter();
char tc=getNextCharacter();
if (tc=='-'){
tc=getNextCharacter();
if (tc=='-'){
//System.out.println("注释行");
String desc=getDescription();
if (this.exeNode!=null)
this.exeNode.setDescription(desc);
}else{
System.err.println("语法错误在"+offset);
return null;
}
}
}else if (match('/')){
String nodeName=this.getNodeName();
if (exeNode.getName().equalsIgnoreCase(nodeName))
exeNode=exeNode.getParent();
else{
System.err.println("期望封闭标签为:"+exeNode.getName()+",实际标签为:"+nodeName);
return null;
}
}else{
String name=this.getNodeName();
XMLNode newNode=new XMLNode(name);
if (root==null){
root=newNode;
exeNode=root;
}else{
exeNode.addChild(newNode);
exeNode=newNode;
}
char tc=this.xml.charAt(offset-1);
if (tc==' ')
getAttributes();
else{
if (tc!='>')
System.err.println(exeNode.getName()+"期待关闭");
}
}
}else{
exeNode.setValue(getValue());
}
}
return root;
}
public static void main(String[] args){
String xml="<?xml version=\"1.0\" encoding=\"GB2312\"?>" +
"<!--注释行--><root desc=\"一个测试的例子\"><book name=\"test\" " +
"value=\"我的\"/><book name=\"跌而\">我的值</book></root>";
XMLParser parser=new XMLParser(xml);
XMLNode root=parser.parse();
System.out.println(root.getName());
Vector nodes = root.getChildNodes();
load(nodes);
// System.out.println(root.toString());
}
static void load(Vector _nodes){
System.out.println(_nodes);
for(int i=0; i<_nodes.size(); i++){
XMLNode tNode = (XMLNode) _nodes.elementAt(i);
System.out.println(tNode.getName());
Enumeration keys=tNode.getAttributes().keys();
while(keys.hasMoreElements()){
String key=(String)keys.nextElement();
String value= tNode.getAttribute(key);
System.out.println(" "+ key+ "=" + value + " ");
}
System.out.println(tNode.getValue());
}
}
}
Java代码
package org.gggeye.easymf.xml;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
/**
* XML Node
* @author wuhua
* <a href=" http://wuhua.3geye.net">我的博客</a>
*
*/
public class XMLNode {
private String name;
private XMLNode parent;
private String value;
private String description;
private Hashtable attributes=new Hashtable();
private Vector childNodes=new Vector();
public XMLNode(String name){
this.name=name;
}
public String getName(){
return this.name;
}
public void setName(String name){
this.name=name;
}
public String getValue(){
return this.value;
}
public void setValue(String value){
this.value=value;
}
public void setAttribute(String name,String value){
this.attributes.put(name,value);
}
public String getAttribute(String attributeName){
return (String)attributes.get(attributeName);
}
public void setDescription(String desc){
this.description=desc;
}
public String getDescription(){
return this.description;
}
public void setParent(XMLNode parent){
this.parent=parent;
}
public XMLNode getParent(){
return this.parent;
}
public void addChild(XMLNode childNode){
this.childNodes.addElement(childNode);
childNode.setParent(this);
}
public String toString(){
StringBuffer xml=new StringBuffer();
if ((this.getDescription()!=null)&&(this.getDescription().length()>0))
xml.append("<!--"+this.getDescription()+"--> ");
xml.append("<");
xml.append(this.getName());
Enumeration keys=this.attributes.elements();
while(keys.hasMoreElements()){
String key=(String)keys.nextElement();
String value=(String)this.attributes.get(key);
xml.append(" "+ key+ "=" + value + " ");
}
if (((this.getValue()==null)||(this.getValue().length()==0))&&(this.childNodes.size()==0)){
xml.append(" /> ");
}else{
xml.append(" >");
if ((this.getValue()!=null)&&(this.getValue().length()>0)){
xml.append(this.getValue());
}
for(int i=0;i<this.childNodes.size();i++)
xml.append(((XMLNode)this.childNodes.elementAt(i)).toString());
xml.append("</"+this.getName()+"> ");
}
return xml.toString();
}
public Hashtable getAttributes() {
return attributes;
}
public Vector getChildNodes() {
return childNodes;
}
}
package org.gggeye.easymf.xml;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
/**
* XML Node
* @author wuhua
* <a href=" http://wuhua.3geye.net">我的博客</a>
*
*/
public class XMLNode {
private String name;
private XMLNode parent;
private String value;
private String description;
private Hashtable attributes=new Hashtable();
private Vector childNodes=new Vector();
public XMLNode(String name){
this.name=name;
}
public String getName(){
return this.name;
}
public void setName(String name){
this.name=name;
}
public String getValue(){
return this.value;
}
public void setValue(String value){
this.value=value;
}
public void setAttribute(String name,String value){
this.attributes.put(name,value);
}
public String getAttribute(String attributeName){
return (String)attributes.get(attributeName);
}
public void setDescription(String desc){
this.description=desc;
}
public String getDescription(){
return this.description;
}
public void setParent(XMLNode parent){
this.parent=parent;
}
public XMLNode getParent(){
return this.parent;
}
public void addChild(XMLNode childNode){
this.childNodes.addElement(childNode);
childNode.setParent(this);
}
public String toString(){
StringBuffer xml=new StringBuffer();
if ((this.getDescription()!=null)&&(this.getDescription().length()>0))
xml.append("<!--"+this.getDescription()+"--> ");
xml.append("<");
xml.append(this.getName());
Enumeration keys=this.attributes.elements();
while(keys.hasMoreElements()){
String key=(String)keys.nextElement();
String value=(String)this.attributes.get(key);
xml.append(" "+ key+ "=" + value + " ");
}
if (((this.getValue()==null)||(this.getValue().length()==0))&&(this.childNodes.size()==0)){
xml.append(" /> ");
}else{
xml.append(" >");
if ((this.getValue()!=null)&&(this.getValue().length()>0)){
xml.append(this.getValue());
}
for(int i=0;i<this.childNodes.size();i++)
xml.append(((XMLNode)this.childNodes.elementAt(i)).toString());
xml.append("</"+this.getName()+"> ");
}
return xml.toString();
}
public Hashtable getAttributes() {
return attributes;
}
public Vector getChildNodes() {
return childNodes;
}
}
类就两个。很简单
看看Demo吧。
Java代码
String _res = Tools.toUTFString(Tools.read(this.getClass().
getResourceAsStream(_url)));
XMLParser tXMLParser = new XMLParser(_res);
XMLNode tXMLNode= tXMLParser.parse();
PlayerItem tMp4 = new PlayerItem(tXMLNode.getAttribute("name"), tXMLNode.getAttribute("encode"));
for(int i=0; i<tXMLNode.getChildNodes().size(); i++){
XMLNode tNode = (XMLNode) tXMLNode.getChildNodes().elementAt(i);
tMp4.addQueue(tNode.getValue());
}
PlayerPanel tMP4Panel = new PlayerPanel(tMp4, getPlayerList());
tMP4Panel.show();
上面的例子是我从自己实现了一个J2ME流媒体播放器抽出来的,大家凑合着看。