javawebday61(省市联动ajax xpath查找元素 xstream用法toXML

省市联动
1、页面
    <select name="province">
        <option>选择省份</option>
    </select>
    <select name="city">
        <option>选择城市</option>
    </select>

2、Servlet
    ProvinceServlet:当页面加载完毕后马上请求这个Servlet
        需要加载china.xml文件,把所有的省的名称使用字符串发送给客户端
3、页面的工作
    获取这个字符串,使用逗号分隔,得到数组
    循环遍历每个字符串(省份的名称),使用每个字符串创建一个<option>添加到<select name="province">这个元素中

4、CityServlet
    CityServlet:当页面选择某个省时,发送请求
    得到省份的名称,加载china.xml文件,查询出该省份对应的元素对象。把这个元素转换成xml字符串,发送给客户端

5、页面的工作
    把<select name="city">中所有子元素删除,但不要删除<option>选择城市</option>
    得到服务器的响应结果:doc
    获取所有的<city>子元素,循环遍历,得到<city>的内容
    使用每个<city>的内容创建一个<option>元素,添加到<select name="city">

XStream
1、作用
    把JavaBean转换为(序列化)xml

2、XStream的jar包
    核心JAR包:xstream-1.4.x.jar
    必须依赖包:xpp3_min-1.1.4c(XML Pull Parser速度很快的XML解析器)

3、使用步骤
    XStream xstream = new XStream();
    String xmlStr = xstream.toXML(javabean);

4、使用细节
    别名:把类型对应的元素名修改
        xstream.alias("china",List.class);让List类型生成的元素名为china
        xstream.alias("province",Province.class):让Province类生成的元素名为province
    使用为属性:默认类的成员,生成的是元素的子元素。希望让类的成员生成元素的属性
        xstream.useAttributeFor(Province.class,"name"):把Province类的名为name成员,生成<province>元素的name属性
    去除集合Collection类型的成员:只需要Collection的内容,而不希望Collection本身也生成一个元素
        xstream.addImplicitCollection(Province.class,"cities"):让Province类的名为cities(是List类型的,内容还会生成元素)的成员不生成元素
    去除类的指定成员,让其不生成xml元素
        xstream.omitField(City.class,"description"):在生成的xml中不会出现City类的。名为description的对应的元素          

JSON
json
    是js提供的一种数据交换格式
json的语法
    {}:是对象
        属性名必须使用双引号括起来。单引不行
        属性值:
            null
            数值
            字符串
            数组:使用[]括起来
            boolean值:truefalse 
3、应用json
    var person = {"name":"zs","age":11,"sex":"male"}                    

这里写图片描述
ajax.jsp

<script type="text/javascript">
function createXMLHttpRequest(){
    try{
        return new XMLHttpRequest();//大多数浏览器
    }catch(e){
        try{
            return ActiveXObject("Msxml2.XMLHTTP");//IE6.0
        }catch(e){
            try{
                return ActiveXObject("Microsoft.XMLHTTP");//IE5.5及更早
            }catch(e){
                alert("什么浏览器?");
                throw e;
            }
        }
    }
}
/*
    1、在文档加载完毕时发送请求,得到所有省份名称,显示在<select name="province"/>中
    2、在选择了新的省份时,发送请求(参数为省名称),得到xml文档,即<province>元素
        解析xml文档,得到其中所有的<city>,再得到每个<city>元素的内容,即市名,使用市名生成<option>,插入到<select name="city">元素中
*/
window.onload = function(){
    /*
        ajax四步,请求ProvinceServlet,得到所有省份名称
        使用每个省份名称创建一个<option>元素,添加到<select name="province">中
    */
    var xmlHttp = createXMLHttpRequest();
    xmlHttp.open("GET", "<c:url value='/ProvinceServlet'/>",true);
    xmlHttp.send(null);
    xmlHttp.onreadystatechange = function(){
        if(xmlHttp.readyState==4 && xmlHttp.status==200){
            //获取服务器响应
            var text = xmlHttp.responseText;
            //使用逗号分隔,得到数组
            var arr = text.split(",");
            //循环遍历每个省份名称,每个名称生成一个option对象,添加到<select>中
            for(var i = 0;i<arr.length;i++){
                var op = document.createElement("option");//创建一个指定名称的元素
                op.value = arr[i];//设置op的实际值为当前的省份名称
                var textNode = document.createTextNode(arr[i]);//创建文本节点
                op.appendChild(textNode);//把文本子节点添加到op元素中,指定其显示值

                document.getElementById("p").appendChild(op);
            }   
        }
    };
        /*
            给<select name="province">添加改变监听
            使用选择的省份名称请求CityServlet,得到<province>元素(xml元素)
            获取<province>元素中所有的<city>元素,遍历之。获取每个<city>的文本内容,即市名称
            使用每个市名称创建<option>元素添加到<select name="city">
        */
        var proSelect = document.getElementById("p");
        proSelect.onchange = function() {
            var xmlHttp = createXMLHttpRequest();
            xmlHttp.open("POST", "<c:url value='/CityServlet'/>", true);
            xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            xmlHttp.send("pname=" + proSelect.value); //把下拉列表中选择的值发送给服务器 
            xmlHttp.onreadystatechange = function() {
                if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                    /*
                        把select中的所有option移除(除了第一个)
                    */
                    var citySelect = document.getElementById("c");
                    //获取其所有子元素
                    var optionEleList = citySelect.getElementsByTagName("option");
                    //循环遍历每个option元素,然后在citySelect中移除
                    while(optionEleList.length>1){//子元素的个数如果大于就循环,等于1就不循环
                        citySelect.removeChild(optionEleList[1]);//总是删除1下标,因为1删除了,2就变成1了
                    }
                    var doc = xmlHttp.responseXML;
                    //得到所有名为city的元素
                    var cityEleList = doc.getElementsByTagName("city"); 
                    //循环遍历每个city元素
                    for(var i = 0;i<cityEleList.length;i++){
                        var cityEle = cityEleList[i];//得到每个city元素
                        var cityName;
                        if(window.addEventListener){//处理浏览器的差异
                            cityName = cityEle.textContent;//支持FireFox等浏览器
                        } else{
                            cityName = cityEle.text;//支持老版IE
                        }
                        //使用市名称创建option元素.添加到<select name ="city">中
                        var op = document.createElement("option");
                        op.value = cityName;
                        //创建文本节点
                        var textNode = document.createTextNode(cityName);
                        op.appendChild(textNode);//把文本节点追加到op元素中
                        //把op添加到<select>元素中

                        citySelect.appendChild(op);
                    }
            }
        }
    };
};
</script>
  </head>

  <body>
<h1>省市联动</h1>
<select name="province" id="p">
    <option>选择省</option>
</select>

<select name="city" ID="c" >
    <option>选择市</option>
</select>
  </body>

ProvinceServlet

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        /*
         * 响应所有省份名称,使用逗号分隔
         */
        /*
         * 1、得到Document对象
         *  创建解析器对象
         *  调用解析器的读方法,传递一个流对象,得到Document
         */
        try {
            SAXReader reader = new SAXReader();
            InputStream input  = this.getClass().getResourceAsStream("/china.xml");
            Document doc = reader.read(input);
            /*
             * 查询所有province的name属性,得到一堆的属性对象
             * 循环遍历,把所有的属性值连接成一个字符串,发送给客户端
             */
            List<Attribute> arrList = doc.selectNodes("//province/@name");//xpath查找 [//]没有深度查找province 查找它的name属性
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < arrList.size(); i++) {
                sb.append(arrList.get(i).getValue());//把每个属性的值存放到sb中
                if(i<arrList.size()-1){
                    sb.append(",");
                }
            }
            response.getWriter().print(sb);
        } catch (DocumentException e) {
            throw new RuntimeException(e);
        }
    }

CityServlet

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        request.setCharacterEncoding("utf-8");
        response.setContentType("text/xml;charset=utf-8");//发送xml时这里要修改
        /*
         * 获取省份名称,加载该省对应的<province>元素
         * 把元素转换成字符串发送给客户端
         */
        /*
         * 1、获取省份名称
         * 2、使用省份名称查找到对应的<province>元素
         * 3、把<province>元素转换成字符串,发送
         */
        try {
            /*
             * 得到Document对象
             */
            SAXReader reader = new SAXReader();
            InputStream input  = this.getClass().getResourceAsStream("/china.xml");
            Document doc = reader.read(input);
            /*
             * 获取参数
             */
            String pname = request.getParameter("pname");//获取省份名称
            Element proEle = (Element) doc.selectSingleNode("//province[@name='"+pname+"']");//province[@name='a']
            String xmlStr = proEle.asXML();//把元素转换成字符串
            response.getWriter().print(xmlStr);
        } catch (DocumentException e) {
            throw new RuntimeException(e);
        }
    }

xxx.xml

<china>
    <province name="a">
        <city>1</city>
        <city>2</city>
    </province>
    <province name="b">
        <city>11</city>
        <city>22</city>
    </province>
</china>    
public class City {
    private String name;//市名
    private String description;//描述
    set get 有参无参
public class Province {
    private String name;
    private List<City> cities = new ArrayList<City>();
    set get 有参无参
    public void addCity(City city){
        cities.add(city);
    }
public class Demo1 {
    //返回javaBean集合
    public List<Province> getProvinceList(){
        Province p1 = new Province();
        p1.setName("a");
        p1.addCity(new City("1","11"));
        p1.addCity(new City("2","22"));

        Province p2 = new Province();
        p2.setName("b");
        p2.addCity(new City("3","33"));
        p2.addCity(new City("4","44"));

        List<Province> provinceList = new ArrayList<Province>();
        provinceList.add(p1);
        provinceList.add(p2);

        return provinceList;
    }
/*
 <list>-->List类型显示list
  <my.demo.Province> -->javabean类型为Province,元素的名称为类的完整名
    <name>a</name>-->javabean的属性名
    <cities>-->javabean的属性名
      <my.demo.City>-->类名
        <name>1</name>-->属性名
        <description>11</description>-->属性名
      </my.demo.City>
      <my.demo.City>
        <name>2</name>
        <description>22</description>
      </my.demo.City>
    </cities>
  </my.demo.Province>
  <my.demo.Province>
    <name>b</name>
    <cities>
      <my.demo.City>
        <name>3</name>
        <description>33</description>
      </my.demo.City>
      <my.demo.City>
        <name>4</name>
        <description>44</description>
      </my.demo.City>
    </cities>
  </my.demo.Province>
</list>

 */
    @Test
    public void fun1(){
        List<Province> proList = getProvinceList();
        /*
         * 创建XStream对象
         * 调用toXML把集合转换成xml字符串
         */
        XStream xstream = new XStream();
        String s = xstream.toXML(proList);
        System.out.println(s);
    }
    /*
     * 别名(alias)
     * 希望:
     *  默认List类型对应<list>元素,希望让List类型对应<china>元素
     *  默认Province类型对应<my.demo.Province>希望让它对应<province>
     *  默认city类型对应<my.demo.City>希望它对应<city>元素
     */
    /*
<china>
  <province>
    <name>a</name>
    <cities>
      <city>
        <name>1</name>
        <description>11</description>
      </city>
      <city>
        <name>2</name>
        <description>22</description>
      </city>
    </cities>
  </province>
  <province>
    <name>b</name>
    <cities>
      <city>
        <name>3</name>
        <description>33</description>
      </city>
      <city>
        <name>4</name>
        <description>44</description>
      </city>
    </cities>
  </province>
</china>
     */
    @Test
    public void fun2(){
        List<Province> proList = getProvinceList();
        XStream xstream = new XStream();
        /*
         * 给指定的类型指定别名
         */
        xstream.alias("china",List.class);//给list类型指定别名china
        xstream.alias("province", Province.class);//给Province指定别名
        xstream.alias("city", City.class);//给City类型指定别名为city
        String s = xstream.toXML(proList);
        System.out.println(s);
    }
    /*
     * 默认javabean的属性都会生成子元素,而现在希望生成元素的属性
     */
    /*
<china>
  <province name="a">
    <cities>
      <city>
        <name>1</name>
        <description>11</description>
      </city>
      <city>
        <name>2</name>
        <description>22</description>
      </city>
    </cities>
  </province>
  <province name="b">
    <cities>
      <city>
        <name>3</name>
        <description>33</description>
      </city>
      <city>
        <name>4</name>
        <description>44</description>
      </city>
    </cities>
  </province>
</china>
     */
    @Test
    public void fun3(){
        List<Province> proList = getProvinceList();
        XStream xstream = new XStream();
        xstream.alias("china",List.class);//给list类型指定别名china
        xstream.alias("province", Province.class);//给Province指定别名
        xstream.alias("city", City.class);//给City类型指定别名为city

        /*
         * 把Province类的name属性,生成<province>元素的属性
         */
        xstream.useAttributeFor(Province.class,"name");
        String s = xstream.toXML(proList);
        System.out.println(s);      
    }
    /*
     * 去除List类型的属性,只把List中的元素生成xml元素
     */
    /*
<china>
  <province name="a">
    <city>
      <name>1</name>
      <description>11</description>
    </city>
    <city>
      <name>2</name>
      <description>22</description>
    </city>
  </province>
  <province name="b">
    <city>
      <name>3</name>
      <description>33</description>
    </city>
    <city>
      <name>4</name>
      <description>44</description>
    </city>
  </province>
</china>
     */
    @Test
    public void fun4(){
        List<Province> proList = getProvinceList();
        XStream xstream = new XStream();
        xstream.alias("china",List.class);//给list类型指定别名china
        xstream.alias("province", Province.class);//给Province指定别名
        xstream.alias("city", City.class);//给City类型指定别名为city
        xstream.useAttributeFor(Province.class,"name");//把Province类的name属性,生成<province>元素的属性

        /*
         * 去除<cities>这样的Collection类型的属性
         * 取出Province类的名为cities的List类型的属性
         */
        xstream.addImplicitCollection(Province.class, "cities");

        String s = xstream.toXML(proList);
        System.out.println(s);      
    }
    /*
     *去除不想要的javabean属性
     *就是让某些javabean属性,不生成对应的xml元素 
     */
    /*
<china>
  <province name="a">
    <city>
      <name>1</name>
    </city>
    <city>
      <name>2</name>
    </city>
  </province>
  <province name="b">
    <city>
      <name>3</name>
    </city>
    <city>
      <name>4</name>
    </city>
  </province>
</china>

     */
    @Test
    public void fun5(){
        List<Province> proList = getProvinceList();
        XStream xstream = new XStream();
        xstream.alias("china",List.class);//给list类型指定别名china
        xstream.alias("province", Province.class);//给Province指定别名
        xstream.alias("city", City.class);//给City类型指定别名为city
        xstream.useAttributeFor(Province.class,"name");//把Province类的name属性,生成<province>元素的属性
        xstream.addImplicitCollection(Province.class, "cities");//去除Province类的名为cities的List类型的属性

        /*
         * 让City类的,名为description属性不生成对应的xml元素
         */
        xstream.omitField(City.class, "description");
        String s = xstream.toXML(proList);
        System.out.println(s);      
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值