开篇:简单XML解析器

我是程序员,多数时间和代码打交道,所以我的博客可能充满了代码。
开篇,XML解析器:
//===================EnumXmlEventType.java=========================//

 

  1. package jiamu.base.xml;
  2. public enum EnumXmlEventType {
  3.     START_READ_HEADER(0),
  4.     START_READ_ATTRIBUTER(1),
  5.     START_READ_NODER(2),
  6.     FINISH_READ_HEADER(3),
  7.     FINISH_READ_ATTRIBUTER(4),
  8.     FINISH_READ_NODER(5);
  9.     public static EnumXmlStatus getEnum(int value) {
  10.         for (EnumXmlStatus enumValue : EnumXmlStatus.values()) {
  11.             if (enumValue.getValue() == value) {
  12.                 return enumValue;
  13.             }
  14.         }
  15.         return null;
  16.     }
  17.     private int value = 0;
  18.     private EnumXmlEventType(int value) {
  19.         this.value = value;
  20.     }
  21.     /**
  22.      * Gets the enumerate object's value.
  23.      * 
  24.      * @return the position of the enumerate object
  25.      */
  26.     public int getValue() {
  27.         return this.value;
  28.     }
  29. }

//===================EnumXmlStatus.java============================//

 

  1. package jiamu.base.xml;
  2. public enum EnumXmlStatus {
  3.     UNKNOWN(0),
  4.     STARTED(1),
  5.     FINISHED(2),
  6.     READVALUE(3),
  7.     READTAG(4);
  8.     public static EnumXmlStatus getEnum(int value) {
  9.         for (EnumXmlStatus enumValue : EnumXmlStatus.values()) {
  10.             if (enumValue.getValue() == value) {
  11.                 return enumValue;
  12.             }
  13.         }
  14.         return null;
  15.     }
  16.     private int value = 0;
  17.     private EnumXmlStatus(int value) {
  18.         this.value = value;
  19.     }
  20.     /**
  21.      * Gets the enumerate object's value.
  22.      * 
  23.      * @return the position of the enumerate object
  24.      */
  25.     public int getValue() {
  26.         return this.value;
  27.     }
  28. }

//===================QXmlElement.java==============================//

 

  1. package jiamu.base.xml;
  2. public class QXmlElement {
  3.     public String        name   = null;
  4.     public EnumXmlStatus status = EnumXmlStatus.UNKNOWN;
  5.     public QXmlElement() {
  6.         this.name = "";
  7.         this.status = EnumXmlStatus.UNKNOWN;
  8.     }
  9. }

//===================QXmlAttributer.java===========================//

 

  1. package jiamu.base.xml;
  2. public class QXmlAttributer extends QXmlElement {
  3.     public String  value          = null;
  4.     public boolean lastAttributer = false;
  5.     public QXmlAttributer() {
  6.         super();
  7.         this.value = "";
  8.     }
  9.     @Override
  10.     public String toString() {
  11.         return this.name + "=/"" + this.value + "/"";
  12.     }
  13. }

//===================QXmlHeader.java===============================//

 

  1. package jiamu.base.xml;
  2. import java.util.Vector;
  3. import jiamu.base.functions.SystemFunctions;
  4. public class QXmlHeader extends QXmlElement {
  5.     public Vector<QXmlAttributer> attributers = null;
  6.     public QXmlHeader() {
  7.         super();
  8.         this.attributers = new Vector<QXmlAttributer>();
  9.     }
  10.     @Override
  11.     public String toString() {
  12.         StringBuilder builder = new StringBuilder();
  13.         builder.append("<?" + this.name);
  14.         for (int i = 0; i < this.attributers.size(); i++) {
  15.             builder.append(" ");
  16.             builder.append(this.attributers.get(i));
  17.         }
  18.         builder.append(" ?>");
  19.         builder.append(SystemFunctions.getLineFeed());
  20.         return builder.toString();
  21.     }
  22. }

//===================QXmlNoder.java================================//

 

  1. package jiamu.base.xml;
  2. import java.util.Vector;
  3. import jiamu.base.functions.StringFunctions;
  4. import jiamu.base.functions.SystemFunctions;
  5. public class QXmlNoder extends QXmlElement {
  6.     public Vector<QXmlAttributer> attributers = null;
  7.     public Vector<QXmlNoder>      noders      = null;
  8.     public Vector<QXmlHeader>     headers     = null;
  9.     public String                 value       = null;
  10.     public QXmlNoder() {
  11.         super();
  12.         this.value = "";
  13.         this.attributers = new Vector<QXmlAttributer>();
  14.         this.noders = new Vector<QXmlNoder>();
  15.         this.headers = new Vector<QXmlHeader>();
  16.     }
  17.     public String getAttributerValue(String name) {
  18.         String result = "";
  19.         for (int i = 0; i < this.attributers.size(); i++) {
  20.             QXmlAttributer xmlAttributer = this.attributers.get(i);
  21.             if (xmlAttributer.name.compareToIgnoreCase(name) == 0) {
  22.                 result = xmlAttributer.value;
  23.                 break;
  24.             }
  25.         }
  26.         return result;
  27.     }
  28.     public QXmlNoder getNoder(String name) {
  29.         QXmlNoder xmlNoder = null;
  30.         for (int i = 0; i < this.noders.size(); i++) {
  31.             if (this.noders.get(i).name.compareToIgnoreCase(name) == 0) {
  32.                 xmlNoder = this.noders.get(i);
  33.                 break;
  34.             }
  35.         }
  36.         return xmlNoder;
  37.     }
  38.     public int getNoderCount() {
  39.         return this.noders.size();
  40.     }
  41.     @Override
  42.     public String toString() {
  43.         StringBuilder builder = new StringBuilder();
  44.         for (int i = 0; i < this.headers.size(); i++) {
  45.             builder.append(this.headers.get(i));
  46.         }
  47.         builder.append("<" + this.name);
  48.         for (int i = 0; i < this.attributers.size(); i++) {
  49.             builder.append(" ");
  50.             builder.append(this.attributers.get(i));
  51.         }
  52.         builder.append(">");
  53.         builder.append(SystemFunctions.getLineFeed());
  54.         for (int i = 0; i < this.noders.size(); i++) {
  55.             builder.append(this.noders.get(i));
  56.         }
  57.         if (!StringFunctions.isEmpty(this.value)) {
  58.             builder.append(this.value);
  59.             builder.append(SystemFunctions.getLineFeed());
  60.         }
  61.         builder.append("</" + this.name + ">");
  62.         builder.append(SystemFunctions.getLineFeed());
  63.         return builder.toString();
  64.     }
  65. }

//===================QXmlStreamEvent.java==========================//

 

  1. package jiamu.base.xml;
  2. public class QXmlStreamEvent {
  3.     public EnumXmlEventType xmlEventType      = null;
  4.     public QXmlNoder        currentNoder      = null;
  5.     public QXmlAttributer   currentAttributer = null;
  6.     public QXmlHeader       currentHeader     = null;
  7.     public QXmlNoder        wholeNoder        = null;
  8.     public QXmlStreamEvent(EnumXmlEventType xmlEventType, QXmlNoder currentNoder, QXmlAttributer currentAttributer, QXmlHeader currentHeader, QXmlNoder wholeNoder) {
  9.         this.xmlEventType = xmlEventType;
  10.         this.currentNoder = currentNoder;
  11.         this.currentAttributer = currentAttributer;
  12.         this.currentHeader = currentHeader;
  13.         this.wholeNoder = wholeNoder;
  14.     }
  15.     @Override
  16.     public String toString() {
  17.         return this.currentNoder.toString();
  18.     }
  19. }

//===================QXmlStreamEventListener.java==================//

 

  1. package jiamu.base.xml;
  2. public interface QXmlStreamEventListener {
  3.     public void eventHappened(QXmlStreamEvent xmlFileEvent);
  4. }

//===================QXmlStream.java===============================//


 

  1. package jiamu.base.xml;
  2. import java.io.BufferedReader;
  3. import java.io.FileInputStream;
  4. import java.io.FileNotFoundException;
  5. import java.io.IOException;
  6. import java.io.InputStreamReader;
  7. import java.io.UnsupportedEncodingException;
  8. import java.net.URL;
  9. import java.util.Vector;
  10. import jiamu.base.exceptions.QException;
  11. public class QXmlStream {
  12.     private static int                      ReadAheadLimit = 10;
  13.     private Vector<QXmlStreamEventListener> listeners      = null;
  14.     private QXmlNoder                       baseNoder      = null;
  15.     private BufferedReader                  in             = null;
  16.     public QXmlStream(BufferedReader bufferedReader) {
  17.         this.listeners = new Vector<QXmlStreamEventListener>();
  18.         this.in = bufferedReader;
  19.     }
  20.     public QXmlStream(String fileName) throws UnsupportedEncodingException, FileNotFoundException {
  21.         this(new BufferedReader(new InputStreamReader(new FileInputStream(fileName), "UTF-8")));
  22.     }
  23.     public QXmlStream(URL url) throws IOException {
  24.         this(new BufferedReader(new InputStreamReader(url.openConnection().getInputStream(), "UTF-8")));
  25.     }
  26.     public void addQXmlFileEventListener(QXmlStreamEventListener l) {
  27.         this.listeners.add(l);
  28.     }
  29.     public QXmlNoder getBaseNoder() {
  30.         return this.baseNoder;
  31.     }
  32.     private void invokeEvent(QXmlStreamEvent xmlFileEvent) {
  33.         for (int i = 0; i < this.listeners.size(); i++) {
  34.             this.listeners.get(i).eventHappened(xmlFileEvent);
  35.         }
  36.     }
  37.     public boolean parse() throws QException {
  38.         try {
  39.             this.baseNoder = new QXmlNoder();
  40.             this.baseNoder.name = "QXMLFILE";
  41.             int readCharacter = this.read();
  42.             while (readCharacter != -1) {
  43.                 if (readCharacter == '<') {
  44.                     // it a starter of tag, follow is the tag.
  45.                     // try to read the next to see if it's an XML starter.
  46.                     readCharacter = this.read(true);
  47.                     if (readCharacter == '?') {
  48.                         // It's an XML header.
  49.                         QXmlHeader xmlHeader = this.parseHeader();
  50.                         if (xmlHeader != null) {
  51.                             this.baseNoder.headers.add(xmlHeader);
  52.                         }
  53.                     } else {
  54.                         // It's an XML node.
  55.                         this.reset();
  56.                         QXmlNoder xmlNoder = this.parseNoder();
  57.                         if (xmlNoder != null) {
  58.                             this.baseNoder.noders.add(xmlNoder);
  59.                         }
  60.                     }
  61.                 }
  62.                 readCharacter = this.read();
  63.             }
  64.             this.in.close();
  65.         } catch (IOException ex) {
  66.             throw new QException(ex, "QXmlFile""parse""");
  67.         }
  68.         return true;
  69.     }
  70.     private QXmlAttributer parseAttributer(QXmlHeader xmlHeader, QXmlNoder xmlNoder) throws QException {
  71.         QXmlAttributer xmlAttributer = new QXmlAttributer();
  72.         this.invokeEvent(new QXmlStreamEvent(EnumXmlEventType.START_READ_ATTRIBUTER, xmlNoder, xmlAttributer, xmlHeader, this.baseNoder));
  73.         int readCharacter = this.read();
  74.         boolean bQuoteSeparator = false;
  75.         while ((readCharacter != -1) && (xmlAttributer.status != EnumXmlStatus.FINISHED)) {
  76.             switch (xmlAttributer.status) {
  77.                 case UNKNOWN: {
  78.                     if (readCharacter != ' ') {
  79.                         xmlAttributer.name += (char) readCharacter;
  80.                         xmlAttributer.status = EnumXmlStatus.STARTED;
  81.                     }
  82.                 }
  83.                     break;
  84.                 case STARTED: {
  85.                     if (readCharacter != '=') {
  86.                         xmlAttributer.name += (char) readCharacter;
  87.                     } else {
  88.                         xmlAttributer.status = EnumXmlStatus.READVALUE;
  89.                         readCharacter = this.read();
  90.                         if (readCharacter == '"') {
  91.                             bQuoteSeparator = true;
  92.                         } else {
  93.                             xmlAttributer.value += (char) readCharacter;
  94.                         }
  95.                     }
  96.                 }
  97.                     break;
  98.                 case FINISHED:
  99.                     break;
  100.                 case READVALUE: {
  101.                     if ((readCharacter == '"') && bQuoteSeparator) {
  102.                         xmlAttributer.status = EnumXmlStatus.FINISHED;
  103.                     } else if ((readCharacter == ' ') && !bQuoteSeparator) {
  104.                         xmlAttributer.status = EnumXmlStatus.FINISHED;
  105.                     } else if (readCharacter == '?') {
  106.                         readCharacter = this.read();
  107.                         if (readCharacter == '>') {
  108.                             xmlAttributer.lastAttributer = true;
  109.                         }
  110.                         xmlAttributer.status = EnumXmlStatus.FINISHED;
  111.                     } else {
  112.                         xmlAttributer.value += (char) readCharacter;
  113.                     }
  114.                 }
  115.                     break;
  116.             }
  117.             if (xmlAttributer.status != EnumXmlStatus.FINISHED) {
  118.                 readCharacter = this.read();
  119.             }
  120.         }
  121.         this.invokeEvent(new QXmlStreamEvent(EnumXmlEventType.FINISH_READ_ATTRIBUTER, xmlNoder, xmlAttributer, xmlHeader, this.baseNoder));
  122.         return xmlAttributer;
  123.     }
  124.     private QXmlHeader parseHeader() throws QException {
  125.         QXmlHeader xmlHeader = new QXmlHeader();
  126.         this.invokeEvent(new QXmlStreamEvent(EnumXmlEventType.START_READ_HEADER, nullnull, xmlHeader, this.baseNoder));
  127.         int readCharacter = this.read();
  128.         while ((readCharacter != -1) && (xmlHeader.status != EnumXmlStatus.FINISHED)) {
  129.             switch (xmlHeader.status) {
  130.                 case UNKNOWN: {
  131.                     xmlHeader.name += (char) readCharacter;
  132.                     xmlHeader.status = EnumXmlStatus.READTAG;
  133.                 }
  134.                     break;
  135.                 case STARTED: {
  136.                     if (readCharacter == '?') {
  137.                         readCharacter = this.read();
  138.                         if (readCharacter == '>') {
  139.                             xmlHeader.status = EnumXmlStatus.FINISHED;
  140.                             break;
  141.                         }
  142.                     } else if (readCharacter != ' ') {
  143.                         this.reset();
  144.                         QXmlAttributer attributer = this.parseAttributer(xmlHeader, null);
  145.                         if (attributer != null) {
  146.                             xmlHeader.attributers.add(attributer);
  147.                             if (attributer.lastAttributer) {
  148.                                 xmlHeader.status = EnumXmlStatus.FINISHED;
  149.                             }
  150.                         }
  151.                     }
  152.                 }
  153.                     break;
  154.                 case READTAG: {
  155.                     if (readCharacter == ' ') {
  156.                         xmlHeader.status = EnumXmlStatus.STARTED;
  157.                     } else {
  158.                         xmlHeader.name += (char) readCharacter;
  159.                     }
  160.                 }
  161.                     break;
  162.                 case FINISHED:
  163.                     break;
  164.                 case READVALUE:
  165.                     break;
  166.             }
  167.             if (xmlHeader.status != EnumXmlStatus.FINISHED) {
  168.                 readCharacter = this.read(true);
  169.             }
  170.         }
  171.         this.invokeEvent(new QXmlStreamEvent(EnumXmlEventType.FINISH_READ_HEADER, nullnull, xmlHeader, this.baseNoder));
  172.         return xmlHeader;
  173.     }
  174.     private QXmlNoder parseNoder() throws QException {
  175.         QXmlNoder xmlNoder = new QXmlNoder();
  176.         this.invokeEvent(new QXmlStreamEvent(EnumXmlEventType.START_READ_NODER, xmlNoder, nullnullthis.baseNoder));
  177.         int readCharacter = this.read();
  178.         while ((readCharacter != -1) && (xmlNoder.status != EnumXmlStatus.FINISHED)) {
  179.             switch (xmlNoder.status) {
  180.                 case UNKNOWN: {
  181.                     xmlNoder.name += (char) readCharacter;
  182.                     xmlNoder.status = EnumXmlStatus.READTAG;
  183.                 }
  184.                     break;
  185.                 case READTAG: {
  186.                     if (readCharacter == ' ') {
  187.                         xmlNoder.status = EnumXmlStatus.STARTED;
  188.                     } else if (readCharacter == '>') {
  189.                         xmlNoder.status = EnumXmlStatus.READVALUE;
  190.                         break;
  191.                     } else {
  192.                         xmlNoder.name += (char) readCharacter;
  193.                     }
  194.                 }
  195.                     break;
  196.                 case STARTED: {
  197.                     if (readCharacter == '/') {
  198.                         readCharacter = this.read();
  199.                         if (readCharacter == '>') {
  200.                             xmlNoder.status = EnumXmlStatus.FINISHED;
  201.                             break;
  202.                         }
  203.                     } else if (readCharacter == '>') {
  204.                         xmlNoder.status = EnumXmlStatus.READVALUE;
  205.                         break;
  206.                     }
  207.                     this.reset();
  208.                     QXmlAttributer attributer = this.parseAttributer(null, xmlNoder);
  209.                     if (attributer != null) {
  210.                         xmlNoder.attributers.add(attributer);
  211.                         if (attributer.lastAttributer) {
  212.                             xmlNoder.status = EnumXmlStatus.READVALUE;
  213.                         }
  214.                     }
  215.                 }
  216.                     break;
  217.                 case FINISHED:
  218.                     break;
  219.                 case READVALUE: {
  220.                     if (readCharacter == '<') {
  221.                         readCharacter = this.read(true);
  222.                         if (readCharacter == '/') {
  223.                             while (readCharacter != '>') {
  224.                                 readCharacter = this.read();
  225.                                 if (readCharacter == -1) {
  226.                                     break;
  227.                                 }
  228.                             }
  229.                             xmlNoder.status = EnumXmlStatus.FINISHED;
  230.                             break;
  231.                         } else if (readCharacter == '!') {
  232.                             String cdataStart = "";
  233.                             cdataStart += (charthis.read();
  234.                             cdataStart += (charthis.read();
  235.                             cdataStart += (charthis.read();
  236.                             cdataStart += (charthis.read();
  237.                             cdataStart += (charthis.read();
  238.                             cdataStart += (charthis.read();
  239.                             cdataStart += (charthis.read();
  240.                             if (cdataStart.compareToIgnoreCase("[CDATA[") == 0) {
  241.                                 // begin reading the CDATA
  242.                                 readCharacter = this.read(true);
  243.                                 while (readCharacter != -1) {
  244.                                     if (readCharacter == ']') {
  245.                                         String cdataEnd = "";
  246.                                         cdataEnd += (charthis.read();
  247.                                         cdataEnd += (charthis.read();
  248.                                         if (cdataEnd.compareToIgnoreCase("]>") == 0) {
  249.                                             // End reading the CDATA
  250.                                             break;
  251.                                         } else {
  252.                                             this.reset();
  253.                                             readCharacter = this.read(true);
  254.                                         }
  255.                                     }
  256.                                     xmlNoder.value += (char) readCharacter;
  257.                                     readCharacter = this.read(true);
  258.                                 }
  259.                                 break;
  260.                             }
  261.                         }
  262.                         this.reset();
  263.                         QXmlNoder xmlSubNoder = this.parseNoder();
  264.                         if (xmlSubNoder != null) {
  265.                             xmlNoder.noders.add(xmlSubNoder);
  266.                         }
  267.                     } else {
  268.                         xmlNoder.value += (char) readCharacter;
  269.                     }
  270.                 }
  271.                     break;
  272.             }
  273.             if (xmlNoder.status != EnumXmlStatus.FINISHED) {
  274.                 readCharacter = this.read(true);
  275.             }
  276.         }
  277.         this.invokeEvent(new QXmlStreamEvent(EnumXmlEventType.FINISH_READ_NODER, xmlNoder, nullnullthis.baseNoder));
  278.         return xmlNoder;
  279.     }
  280.     private int read() throws QException {
  281.         return this.read(false);
  282.     }
  283.     private int read(boolean marked) throws QException {
  284.         try {
  285.             if (marked) {
  286.                 this.in.mark(QXmlStream.ReadAheadLimit);
  287.             }
  288.             int result = this.in.read();
  289.             return result;
  290.         } catch (IOException ex) {
  291.             throw new QException(ex, "QXmlFile""read""");
  292.         }
  293.     }
  294.     public void removeXmlFileEventListener(QXmlStreamEventListener l) {
  295.         this.listeners.remove(l);
  296.     }
  297.     private void reset() throws QException {
  298.         try {
  299.             this.in.reset();
  300.         } catch (IOException ex) {
  301.             throw new QException(ex, "QXmlFile""reset""");
  302.         }
  303.     }
  304. }

完。

这个博客编辑器真不好使。。难道和我的IE8有关。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值