一、Dom4j的使用    在介绍公交线路开发之前,先简单介绍下Dom4j的使用,因为公交线路查询引用的是爱帮公交api,调用结果为xml格式文件,故用到了Dom4j这个包,当然还有其他的包来读取xml文件,如XStream等,详见柳峰老师《微信公众平台应用开发方法、技巧与案例》一书,有详细介绍。
    这里先给一个样例代码,供大家参考:
   1.利用Dom4j创建xml文件

Java代码 

1. package org.elvis.course.dom4j;
2. 
3. import java.io.FileOutputStream;
4. 
5. import org.dom4j.Attribute;
6. import org.dom4j.Document;
7. import org.dom4j.DocumentHelper;
8. import org.dom4j.Element;
9. import org.dom4j.io.OutputFormat;
10. import org.dom4j.io.XMLWriter;
11. 
12. 
13. 
14. public class MyDom4j {
15. public static void main(String[] args){
16. //创建文档
17.     Document document = DocumentHelper.createDocument();
18. //设置文档DocType,这里为了举例,添加加hibernate的DocType
19. "hibernate-configuration",
20. "-//Hibernate/Hibernate Configuration DTD 3.0//EN",
21. "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd");
22. // 文档增加节点,即根节点,一个文档只能有一个根节点,多加出错
23. "skills");
24. // 添加注释
25. "第一个技能");
26. // 根节点下添加节点
27. "skill");
28. // 节点添加属性
29. "name", "独孤九剑");
30. // 节点下添加节点
31. "info");
32. // 节点设置内容数据
33. "为独孤求败所创,变化万千,凌厉无比。其传人主要有风清扬、令狐冲。");
34.         
35. // 同理增加其他节点,内容,属性等
36. "skill");
37. "name", "葵花宝典");
38. "info");
39. "宦官所创,博大精深,而且凶险至极。练宝典功夫时,首先要自宫净身。");
40. /**
41.         * 第二种方法增加节点,内容,属性等。先创建节点,属性,然后使用add加入。
42.         */
43. // 创建节点
44. "skill");
45. // 将节点加入到根节点中
46.         root.add(third);
47. // 创建属性,第一个参数指定了拥有者,也可以为null,指定拥有者
48. "name", "北冥神功");
49. // 将属性加入到节点上
50.         third.add(name);
51. // 创建子节点并加入到节点中
52. "info");
53. "逍遥派的顶级内功之一,能吸人内力转化为自己所有,威力无穷。");
54.         third.add(info3);
55.         
56. try {
57. // 创建格式化类
58.         OutputFormat format = OutputFormat.createPrettyPrint();
59. // 设置编码格式,默认UTF-8
60. "UTF-8");
61. // 创建输出流,此处要使用Writer,需要指定输入编码格式,使用OutputStream则不用
62. new FileOutputStream("d:/skills.xml");
63. // 创建xml输出流
64. new XMLWriter(fos, format);
65. // 生成xml文件
66.         writer.write(document);
67.         writer.close();
68. catch (Exception e) {
69.         e.printStackTrace();
70.         }
71.         
72.   }
73. }


    2.读取刚才创建的skills.xml文件

Java代码 

1. package org.elvis.course.dom4j;
2. 
3. import java.io.File;
4. import java.util.Iterator;
5. import java.util.List;
6. 
7. import org.dom4j.Document;
8. import org.dom4j.DocumentException;
9. import org.dom4j.Element;
10. import org.dom4j.io.SAXReader;
11. import org.xml.sax.SAXException;
12. 
13. public class ReadDom4j {
14. 
15. /**
16.     * @param args
17.     * @throws SAXException
18.     */
19. public static void main(String[] args) throws SAXException {
20. // TODO Auto-generated method stub
21.     
22. try {
23. new SAXReader();
24. //读取刚才创建的XML文件
25. "http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
26. new File("d:/skills.xml"));
27. //取根节点
28.       Element root = document.getRootElement();
29. //取二级节点
30. "skill");
31. //取三级节点
32. "skill");
33. //取节点为Info的值
34. 0).element("info").getText();
35. "info").getText();
36.       System.out.println(ss);
37.       System.out.println(ss1);
38. catch (DocumentException e) {
39. // TODO Auto-generated catch block
40.       e.printStackTrace();
41.     }
42. 
43.   }
44. 
45. }


Dom4j的Jar包:


二、公交线路查询开发


    1.主要代码

Java代码 

1. package org.elvis.yy.gongjiao;
2. 
3. import java.io.InputStream;
4. import java.io.UnsupportedEncodingException;
5. import java.net.HttpURLConnection;
6. import java.net.URL;
7. import java.util.List;
8. 
9. import org.dom4j.Document;
10. import org.dom4j.Element;
11. import org.dom4j.io.SAXReader;
12. import org.elvis.yy.yinyue.Music;
13. 
14. public class AibanggongjiaoService {
15. /**
16.     * 爱帮公交线路查询
17.     * 根据城市和关键字(线路)查询
18.     * @param city  城市
19.     * @param q  线路
20.     * @return gongjiao
21.     */
22. public static gongjiao searchGongjiao(String city, String q) {
23. // 爱帮api地址
24. "http://openapi.aibang.com/bus/lines?app_key=b7fb1e41aa104e9c24b81894d8e5ab48&city={city}&q={q}";
25. // 对城市和线路进行编码
26. "{city}", urlEncodeUTF8(city));
27. "{q}", urlEncodeUTF8(q));
28. // 处理名称、作者中间的空格
29. "\\+", "%20");
30. 
31. // 查询并获取返回结果
32.     InputStream inputStream = httpRequest(requestUrl);
33. // 从返回结果中解析出gongjiao
34.     gongjiao gj = parseGongjiao(inputStream);
35. 
36.   
37. return gj;
38.   }
39. 
40. /**
41.     * UTF-8编码
42.     *
43.     * @param source
44.     * @return
45.     */
46. private static String urlEncodeUTF8(String source) {
47.     String result = source;
48. try {
49. "UTF-8");
50. catch (UnsupportedEncodingException e) {
51.       e.printStackTrace();
52.     }
53. return result;
54.   }
55. 
56. /**
57.     * 发送http请求取得返回的输入流
58.     *
59.     * @param requestUrl 请求地址
60.     * @return InputStream
61.     */
62. private static InputStream httpRequest(String requestUrl) {
63. null;
64. try {
65. new URL(requestUrl);
66.       HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();
67. true);
68. "GET");
69.       httpUrlConn.connect();
70. // 获得返回的输入流
71.       inputStream = httpUrlConn.getInputStream();
72. catch (Exception e) {
73.       e.printStackTrace();
74.     }
75. return inputStream;
76.   }
77. 
78. /**
79.     * 解析音乐参数
80.     *
81.     * @param inputStream 百度音乐搜索API返回的输入流
82.     * @return Music
83.     */
84. @SuppressWarnings("unchecked")
85. private static gongjiao parseGongjiao(InputStream inputStream) {
86. null;
87. try {
88. // 使用dom4j解析xml字符串
89. new SAXReader();
90.       Document document = reader.read(inputStream);
91. // 得到xml根元素
92.       Element root = document.getRootElement();
93. // result_num表示查询得公交路线数量
94. "result_num").getText();
95.       
96. // 当公交线路大于0时
97. if (!"0".equals(num)) {
98. // 公交信息根节点
99. "lines");
100. 0).elements("line");
101.         
102. 0).element("name").getText();
103. 0).element("info").getText();
104. 0).element("stats").getText();
105. 1).element("stats").getText();
106. new gongjiao();
107. //获取公交始发站和终点站信息
108.         gj.setName(name);
109. //获取公交价格
110.         gj.setJiage(info);
111. //获取公交正向的各个站点
112.         gj.setZhengxiang(stats);
113. //获取公交反向的信息
114.         gj.setFanxiang(f_stats);
115.       }
116. catch (Exception e) {
117.       e.printStackTrace();
118.     }
119. return gj;
120.   }
121. 
122. // 测试方法
123. public static void main(String[] args) {
124. "营口", "206路");
125. "公交名称:" + gj.getName());
126. "公交价格:" + gj.getJiage());
127. "正向公交信息:" + gj.getZhengxiang());
128. "反向公交信息:" + gj.getFanxiang());
129.   }
130. }



gongjiao类

1.  package org.elvis.yy.gongjiao;
2.  
3.  public class gongjiao {
4.     public String getName() {
5.                  return name;
6.          }
7.          public void setName(String name) {
8.                  this.name = name;
9.          }
10.          public String getJiage() {
11.                  return jiage;
12.          }
13.          public void setJiage(String jiage) {
14.                  this.jiage = jiage;
15.          }
16.          public String getZhengxiang() {
17.                  return zhengxiang;
18.          }
19.          public void setZhengxiang(String zhengxiang) {
20.                  this.zhengxiang = zhengxiang;
21.          }
22.          public String getFanxiang() {
23.                  return fanxiang;
24.          }
25.          public void setFanxiang(String fanxiang) {
26.                  this.fanxiang = fanxiang;
27.          }
28.  private String name;
29.     private String jiage;
30.     private String zhengxiang;
31.     private String fanxiang;
32.     
33.  }



微信调用

1.  if(content.startsWith("公交")){
2.         //将公交2个字及公交后面的+、空格、-等特殊符号去掉
3.        String keyWord = content.replaceAll("^公交[\\+ ~!@#%^-_=]?", "").trim();
4.         if(keyWord.equals("")){
5.          textMessage.setContent("使用指南:输入“翻译”、“歌曲”、“公交”会有相应回复!");
6.          respXml = MessageUtil.messageToXml(textMessage);
7.         }else{
8.         String[] kwArr = keyWord.split("@");
9.        //城市
10.         String city = kwArr[0];
11.          String q = kwArr[1];
12.         //搜索公交信息
13.         gongjiao gj = AibanggongjiaoService.searchGongjiao(city, q);
14.         //未搜索到公交信息
15.         if(gj == null){
16.         textMessage.setContent("对不起,没有找到你找的<"+city+">城市或<“+q+”>公交线路。");       
17.         respXml = MessageUtil.messageToXml(textMessage);
18.         }else{
19.         StringBuffer buffer = new StringBuffer();
20.         buffer.append(emoji.emojis(0x1F68C)).append(gj.getName()).append("\n\n");
21.         buffer.append(emoji.emojis(0x1F68C)).append(gj.getJiage()).append("\n");
22.         buffer.append(emoji.emojis(0x1F68C)).append(gj.getZhengxiang()).append("\n");
23.                textMessage.setContent(buffer.toString());        
24.         respXml = MessageUtil.messageToXml(textMessage);
25.          }
26.  }