posts - 11,  comments - 14,  trackbacks - 0
          Webservice交互中需要雙方約定數據格式,用XML表示數據庫記錄是不錯的選擇。
          先定義個DTD:

          <!--
               DTD for the Xml-Format-String used to transmit business data
          -->
          <!-- The "DBSET" element is the root of the Xml-Format-String-->
          <!ELEMENT DBSET ( R* )>
          <!ATTLIST DBSET  RESULT  #IMPLIED>

          <!-- The "R" element describes a record-->
          <!ELEMENT R ( C+ )>

          <!-- The "C" element describes a column-->
          <!ELEMENT C ( #PCDATA ) >
          <!ATTLIST C  N  #REQUIRED>

          用R代表ROW,C代表COLUMN,N代表NAME(R、C和N降低了可讀性,但節約了傳輸字節數)

          數據庫記錄示例:

            FIRST_NAME   LAST_NAME
          1 seng                   tang
          2 wukong              sun

          XML示例:
          <?xml version='1.0' encoding='UTF-8'?>
          <DBSET RESULT="2">
           <R>
            <C N="firstName">wukong</C>
            <C N="lastName">sun</C>
           </R>
           <R>
            <C N="firstName">sen</C>
            <C N="lastName">tang</C>
           </R>
          </DBSET>

          再來個嵌套的示例:
          <DBSET>
            <R>
              <C N="province">浙江</C>
              <C N="cityList">
                <DBSET>
                  <R>
                    <C N="en">HangZhou</C>
                    <C N="zh">杭州</C>
                  <R>
                  <R>
                    <C N="en">JinHua</C>
                    <C N="zh">金華</C>
                  <R>
                </DBSET>
              </C>
            <R>
          </DBSET>

          有個這個可以表示任何復雜的業務數據。

          剩下的問題就是XML的組成及解析了。
          用一個專門的類負責組織及解析XML,組裝XML方法的參數為Map(一個R節點)或List<Map>(多個R節點)
          同樣解析后的結果為Map(一個R節點)或List<Map>(多個R節點),
          這樣開發直接打交道的就是Map或List<Map>了(Map和List可是很容易操作的哦)。

          接下來看看解析工具
          以前我是用Dom4j解析的,后來改成了用Stax,經測試,速度較前者提高了1-2倍。
          Axis2宣稱比Axis1速度快了很多,很大程度上歸功于XML的解析改為了Stax的方式吧。
          關于Stax的使用網上有很多的,由于性能要求高,我用的是Streaming Api,jar是Axis2中帶的(順便說下Axis2的部署嚇死人,太多東西而實際上很多用不到),
          兩個jar:geronimo-stax-api_1.0_spec-1.0.1.jarwstx-asl-3.2.4.jar

          曬代碼:
          import java.io.StringReader;
          import java.io.StringWriter;
          import java.util.ArrayList;
          import java.util.HashMap;
          import java.util.Iterator;
          import java.util.List;
          import java.util.Map;

          import javax.xml.stream.XMLInputFactory;
          import javax.xml.stream.XMLOutputFactory;
          import javax.xml.stream.XMLStreamException;
          import javax.xml.stream.XMLStreamReader;
          import javax.xml.stream.XMLStreamWriter;

          import epm.core.exception.EPMRuntimeException;

          /**
           * Utility class to convert one Object to Xml-Format-String and back again. The
           * Xml-Format-String is based on the following DTD.<p/> <code>
           * &lt;!-- The "DBSET" element is the root of the Xml-Format-String--&gt; <br/>
           * &lt;!ELEMENT DBSET ( R* )&gt; <br/>
           * &lt;!ATTLIST DBSET  RESULT  #IMPLIED&gt; <p/>
           * &lt;!-- The "R" element describes a record--&gt; <br/>
           * &lt;!ELEMENT R ( C+ )&gt; <p/>
           * &lt;!-- The "C" element describes a column--&gt; <br/>
           * &lt;!ELEMENT C ( #PCDATA ) &gt; <br/>
           * &lt;!ATTLIST C  N  #REQUIRED&gt; <p/></code>
           * 
           * 
           * Author: jinn
          */

          public class XfsUtil {
              
          // ----------------------------- Construct one Object to Xml-Format-String
              public static String toXfs(Object object) {
                  
          if (object == null{
                      
          return null;
                  }
           else if (object instanceof List) {
                      
          return toXfs((List) object);
                  }
           else if (object instanceof Map) {
                      
          return toXfs((Map) object);
                  }
           else {
                      StringWriter buffer 
          = new StringWriter();
                      XMLStreamWriter writer 
          = createStartDocument(buffer);
                      
          try {
                          writer.writeStartElement(
          "DBSET");
                          writer.writeAttribute(
          "RESULT", object.toString());
                          writer.writeEndElement();
                      }
           catch (XMLStreamException e) {
                          
          // TODO Auto-generated catch block
                          e.printStackTrace();
                      }

                      
          return docAsXml(writer, buffer);
                  }

              }


              
          public static String toXfs(Map map) {
                  StringWriter buffer 
          = new StringWriter();
                  XMLStreamWriter writer 
          = createStartDocument(buffer);
                  
          try {
                      writer.writeStartElement(
          "DBSET");
                      addMapToRowElement(map, writer);
                      writer.writeEndElement();
                  }
           catch (XMLStreamException e) {
                      
          // TODO Auto-generated catch block
                      e.printStackTrace();
                  }

                  
          return docAsXml(writer, buffer);
              }


              
          public static String toXfs(List<Map> mapList) {
                  StringWriter buffer 
          = new StringWriter();
                  XMLStreamWriter writer 
          = createStartDocument(buffer);
                  addListToDbsetElement(mapList, writer);
                  
          return docAsXml(writer, buffer);
              }


              
          private static XMLStreamWriter createStartDocument(StringWriter buffer) {
                  XMLOutputFactory outputFactory 
          = XMLOutputFactory.newInstance();
                  outputFactory.setProperty(
          "javax.xml.stream.isRepairingNamespaces",
                          
          new Boolean(true));
                  XMLStreamWriter writer 
          = null;
                  
          try {
                      writer 
          = outputFactory.createXMLStreamWriter(buffer);
                      writer.writeStartDocument(
          "UTF-8""1.0");
                      writer.writeCharacters(
          "\r\n");
                  }
           catch (XMLStreamException e) {
                      
          // TODO Auto-generated catch block
                      e.printStackTrace();
                  }

                  
          return writer;
              }


              
          private static String docAsXml(XMLStreamWriter writer, StringWriter buffer) {
                  
          try {
                      writer.writeEndDocument();
                  }
           catch (XMLStreamException e) {
                      
          // TODO Auto-generated catch block
                      e.printStackTrace();
                  }

                  
          return buffer.toString();
              }


              
          private static void addMapToRowElement(Map map, XMLStreamWriter writer) {
                  
          try {
                      writer.writeStartElement(
          "R");
                      Iterator keyValuePairs 
          = map.entrySet().iterator();
                      
          for (int i = 0; i < map.size(); i++{
                          Map.Entry entry 
          = (Map.Entry) keyValuePairs.next();
                          String key 
          = (String) entry.getKey();
                          Object value 
          = entry.getValue();
                          writer.writeStartElement(
          "C");
                          writer.writeAttribute(
          "N", key);
                          
          if (value == null || value instanceof String) {
                              writer.writeCharacters(value 
          == null ? "" : (String) value);
                          }
           else if (value instanceof List) {
                              addListToDbsetElement((List) value, writer);
                          }
           else {
                              writer.writeCharacters(value.toString());
                          }

                          writer.writeEndElement();
                      }

                      writer.writeEndElement();
                  }
           catch (XMLStreamException e) {
                      
          // TODO Auto-generated catch block
                      e.printStackTrace();
                  }

              }


              
          private static void addListToDbsetElement(List srcList,
                      XMLStreamWriter writer) 
          {
                  
          try {
                      writer.writeStartElement(
          "DBSET");
                      writer.writeAttribute(
          "RESULT", Integer.toString(srcList.size()));
                      Iterator it 
          = srcList.iterator();
                      
          while (it.hasNext()) {
                          Map map 
          = (Map) it.next();
                          addMapToRowElement(map, writer);
                      }

                      writer.writeEndElement();
                  }
           catch (XMLStreamException e) {
                      
          // TODO Auto-generated catch block
                      e.printStackTrace();
                  }

              }


              
          // ----------------------------- parese Xml-Format-String to one Object

              
          public static int getDbsetAttribute(String xmlStr) {
                  XMLInputFactory inputFactory 
          = XMLInputFactory.newInstance();
                  String result 
          = "0";
                  XMLStreamReader reader 
          = null;
                  
          try {
                      reader 
          = inputFactory
                              .createXMLStreamReader(
          new StringReader(xmlStr));
                      
          while (reader.hasNext()) {
                          
          if (dbsetStart(reader)) {
                              result 
          = reader.getAttributeValue(0);
                              
          break;
                          }

                          reader.next();
                      }

                  }
           catch (XMLStreamException e) {
                      e.printStackTrace();
                      
          throw new EPMRuntimeException("server.badXmlStr",
                              
          new String[] { xmlStr });
                  }
           finally {
                      
          try {
                          reader.close();
                      }
           catch (XMLStreamException e) {
                          e.printStackTrace();
                      }

                  }


                  
          return Integer.parseInt(result);
              }


              
          public static List<Map> toList(String xmlStr) {
                  XMLInputFactory inputFactory 
          = XMLInputFactory.newInstance();
                  List list 
          = new ArrayList();
                  
          try {
                      XMLStreamReader reader 
          = inputFactory
                              .createXMLStreamReader(
          new StringReader(xmlStr));
                      list 
          = paresDbsetElementToList(reader);
                      reader.close();
                  }
           catch (XMLStreamException e) {
                      e.printStackTrace();
                      
          throw new EPMRuntimeException("server.badXmlStr",
                              
          new String[] { xmlStr });
                  }

                  
          return list;
              }


              
          private static List paresDbsetElementToList(XMLStreamReader reader) {
                  List list 
          = new ArrayList();
                  Map map 
          = new HashMap();
                  
          try {
                      
          while (reader.hasNext()) {
                          
          if (rowStart(reader)) {
                              map 
          = parseRowElementToMap(reader, list);
                          }
           else if (dbsetEnd(reader)) {
                              
          break;
                          }

                          reader.next();
          // 獲取下一個解析事件
                      }

                  }
           catch (Exception e) {
                      e.printStackTrace();
                  }


                  
          return list;
              }


              
          private static Map parseRowElementToMap(XMLStreamReader reader, List list) {
                  Map map 
          = new HashMap();
                  
          try {
                      
          while (reader.hasNext()) {
                          
          int eventType = reader.getEventType();
                          
          if (colStart(reader)) {
                              String key 
          = reader.getAttributeValue(0);
                              Object value;
                              
          try {
                                  String colText 
          = reader.getElementText();
                                  value 
          = (colText == null || "null"
                                          .equalsIgnoreCase(colText)) 
          ? "" : colText;
                              }
           catch (Exception e) {
                                  reader.next();
                                  value 
          = paresDbsetElementToList(reader);
                              }


                              map.put(key, value);

                          }
           else if (rowEnd(reader)) {
                              list.add(map);
                              
          break;
                          }

                          reader.next();
          // 獲取下一個解析事件
                      }

                  }
           catch (XMLStreamException e) {
                      
          // TODO Auto-generated catch block
                      e.printStackTrace();
                  }

                  
          return map;
              }


              
          private static boolean dbsetStart(XMLStreamReader reader) {
                  
          return reader.getEventType() == XMLStreamReader.START_ELEMENT
                          
          && "DBSET".equals(reader.getLocalName());
              }


              
          private static boolean dbsetEnd(XMLStreamReader reader) {
                  
          return reader.getEventType() == XMLStreamReader.END_ELEMENT
                          
          && "DBSET".equals(reader.getLocalName());
              }


              
          private static boolean rowStart(XMLStreamReader reader) {
                  
          return reader.getEventType() == XMLStreamReader.START_ELEMENT
                          
          && "R".equals(reader.getLocalName());
              }


              
          private static boolean rowEnd(XMLStreamReader reader) {
                  
          return reader.getEventType() == XMLStreamReader.END_ELEMENT
                          
          && "R".equals(reader.getLocalName());
              }


              
          private static boolean colStart(XMLStreamReader reader) {
                  
          return reader.getEventType() == XMLStreamReader.START_ELEMENT
                          
          && "C".equals(reader.getLocalName());
              }


              
          private static boolean colEnd(XMLStreamReader reader) {
                  
          return reader.getEventType() == XMLStreamReader.END_ELEMENT
                          
          && "C".equals(reader.getLocalName());
              }


              
          public static void main(String[] args) throws XMLStreamException {
                  List list 
          = new ArrayList();
                  Map map 
          = new HashMap();
                  map.put(
          "firstName""wukong");
                  map.put(
          "lastName""sun");
                  list.add(map);
                  Map map2 
          = new HashMap();
                  map2.put(
          "firstName""sen");
                  map2.put(
          "lastName""tang");
                  list.add(map2);

                  Map m 
          = new HashMap();
                  m.put(
          "nested", list);
                  String dataXmlStr 
          = toXfs(list);
                  System.out.println(dataXmlStr);
                  
                  List parsedList 
          = toList(dataXmlStr);
                  System.out.println(
          "result:" + parsedList);
              }

          }

          posted on 2008-07-18 15:13 jinn 閱讀(2052) 評論(1)  編輯  收藏 所屬分類: Jave/Webservice

          FeedBack:
          # re: 用Stax組裝及解析XML
          2008-07-19 10:09 | 高手
          http://www.HelloCTO.com
          成千視頻,上萬文章,技術資料與您共享  回復  更多評論
            

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2008年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          常用鏈接

          留言簿(3)

          隨筆分類

          文章分類

          相冊

          網站鏈接

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 洞头县| 安仁县| 上栗县| 顺义区| 景洪市| 海淀区| 原平市| 南部县| 蓝山县| 当雄县| 水城县| 荣昌县| 柳州市| 衡东县| 石城县| 蓬溪县| 庆安县| 图木舒克市| 綦江县| 漠河县| 加查县| 远安县| 临安市| 香格里拉县| 英山县| 越西县| 江阴市| 许昌县| 昔阳县| 十堰市| 治多县| 察哈| 景东| 永胜县| 依兰县| 如皋市| 乡宁县| 裕民县| 河西区| 大理市| 茌平县|