Andorid中使用Jsoup解析库解析XML、HTML、Dom节点---第三方库学习笔记(三)

XML介绍:

XML简介:

  • XML,可扩展标记语言,标准通用标记语言的子集。
  • 一种用于标记电子文件使其具有结构性的标记语言。
  • 它可以用来标记数据、定义数据类型
  • 是一种允许用户对自己的标记语言进行定义的源语言。
  • 非常适合万维网传输
  • 提供统一方法描述和交换独立于应用程序或供应商的结构化数据

XML的特点:

  • XML是一种标记语言,很类似HTML
  • XML的设计宗旨是传输数据,而非显示数据
  • XML标签没有被预定义,需要自行定义标签
  • XML被设计为具有自我描述性
  • XML是W3C的推荐标准

    XML与HTML对比:

    1. XML和HTML是为不同目的而设计:
  • XML被设计为传输和存储数据,其焦点是数据的内容

  • HTML被设计用来显示数据,其焦点是数据的外观
  • HTML旨在显示数据,而XML旨在传输数据

2.XML仅仅是纯文本
有能力处理纯文本的软件都可以处理XML。不过能够读懂XML的应用程序可以有针对的处理XML的标签。标签的功能性意义依赖于应用程序的特性。

3.XML没有预定义的标签
在HTML中使用的标签(以及HTML的结构)是预定义的。HTML文档只使用在HTML标准中定义过的标签。

XML的语法规则:

  1. 在XML中,省略关闭标签是非法的,所有标签都必须有关闭标签。
  2. XML标签对对大小写敏感
  3. XML必须正确的嵌套
  4. XML文档必须有根元素
  5. XML的属性值必须加引号
  6. XML中,空格会被保留

元素可以包含其他元素、文本、或者两者的混合物。元素也可以拥有属性。

<bookstore>
  <book category="children">
    <title>Harry Potter</title>
    <author>JK.Rowing</author>
    <year>2005</year>
    <price>29.9</price>
  </book>
</bookstore>
<bookstore><book>都拥有元素内容,因为他们包含了其他元素。
<author>只有文本内容,因为仅包含文本。
在上例中,只有<book>元素属性(category="children")

使用JDK自带的API(Document)解析和生成XML文件:
需要解析的XML文件:

<?xml version="1.0" encoding="utf-8"?>
    <languages cat="it">
        <lan id="1">
            <name>Java</name>
            <ide>Eclipse</ide>
        </lan>
        <lan id="2">
            <name>Swift</name>
            <ide>XCode</ide>
        </lan>
        <lan id="3">
            <name>C#</name>
            <ide>Visual Studio</ide>
        </lan>
    </languages>
package com.example.myxmltest;

import java.io.InputStream;
import java.io.StringWriter;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity {
    private TextView text;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();

        dealXML();//解析XML文件

//        createXML();//创建XML文件
    }

    /**
     * 创建XML文件
     */
    private void createXML() {
        try {
        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = builderFactory.newDocumentBuilder();
        Document document = builder.newDocument();
        //创建根节点元素
        Element root = document.createElement("Languages");
        //为根节点元素设置属性值
        root.setAttribute("cat", "it");

        //第一个子节点
        //创建子节点元素,并为子节点元素设置属性值
        Element lan1 = document.createElement("lan");
        lan1.setAttribute("id", "1");
        //创建子节点的子节点元素,并为其设置内容属性值
        Element name1 = document.createElement("name");
        name1.setTextContent("Java");
        Element ide1 = document.createElement("ide");
        ide1.setTextContent("Eclipse");
        //将这些内容节点添加到子节点中作为子节点的子节点
        lan1.appendChild(name1);
        lan1.appendChild(ide1);

        //第二个子节点
        //创建子节点元素,并为子节点元素设置属性值
        Element lan2 = document.createElement("lan");
        lan2.setAttribute("id", "2");
        //创建子节点的子节点元素,并为其设置内容属性值
        Element name2 = document.createElement("name");
        name2.setTextContent("Swift");
        Element ide2 = document.createElement("ide");
        ide2.setTextContent("XCode");
        //将这些内容节点添加到子节点中作为子节点的子节点
        lan2.appendChild(name2);
        lan2.appendChild(ide2);

        //第三个子节点
        //创建子节点元素,并为子节点元素设置属性值
        Element lan3 = document.createElement("lan");
        lan3.setAttribute("id", "3");
        //创建子节点的子节点元素,并为其设置内容属性值
        Element name3 = document.createElement("name");
        name3.setTextContent("C#");
        Element ide3 = document.createElement("ide");
        ide3.setTextContent("Visual studio");
        //将这些内容节点添加到子节点中作为子节点的子节点
        lan3.appendChild(name3);
        lan3.appendChild(ide3);

        //将子节点添加到根节点中作为根节点的子节点
        root.appendChild(lan1);
        root.appendChild(lan2);
        root.appendChild(lan3);
        //添加根节点元素
        document.appendChild(root);

        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty("encoding", "utf-8");
        StringWriter sw = new StringWriter();
        transformer.transform(new DOMSource(document), new StreamResult(sw));
        text.setText(sw.toString());

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

    /**
     * 用JDK自带的API(Document)解析XML文件
     */
    private void dealXML() {
        try {
            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = builderFactory.newDocumentBuilder();
            InputStream inputStream = getAssets().open("languages.xml");
            Document document = builder.parse(inputStream);
            //当前的element代表根节点中所有内容
            Element element = document.getDocumentElement();
            NodeList nodeList = element.getElementsByTagName("lan");
            for (int i = 0; i < nodeList.getLength(); i++) {
                Element lan = (Element) nodeList.item(i);
                text.append(lan.getAttribute("id")+"\n");
                text.append(lan.getElementsByTagName("name").item(0).getTextContent()+"\n");
                text.append(lan.getElementsByTagName("ide").item(0).getTextContent()+"\n");
            }


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

    private void initView() {
        text = (TextView) findViewById(R.id.text);
    }
}

HTML、XML等Dom节点类解析库的使用:

Jsoup简介:
jsoup是一款Java的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于JQuery的操作方法来取出和操作数据。

Jsoup特点:

  • HTML、XML、自定义DOM格式文本解析
  • 可操作HTML元素、属性、文本
  • 适用于采集解析网站HTML
  • DOM解析功能非常强大

Jsoup基本用法:

  1. 分析Html或Dom文本的结点标签结构
  2. 寻找你要解析的那个内容部分所在的结点标记
  3. 调用Jsoup API解析结点内容

代码演示:

  1. 使用Jsoup载入Html数据
  2. 使用Jsoup解析并提取HTML元素
  3. 使用Jsoup修改数据
  4. 使用Jsoup HTML文档清理
package com.test.Jsoup;

import java.io.File;
import java.io.IOException;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.safety.Whitelist;
import org.jsoup.select.Elements;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;

import com.example.myxmltest.R;

/**
 * Jsoup的四个功能的基本使用方法
 * @author Administrator
 *
 */
public class JsoupTest extends Activity {
    private String html = "<html><head><title>Jsoup的用法</title></head><body><p><a href='http://baidu.com'>这里是Jsoup项目的相关文章</a></p></body></html>";
    private String url = "http://baidu.com";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        /*
         * 1.使用 Jsoup 载入 Html 数据功能
         * 数据内容可以是:html文本、url、本地html
         */

        //1.html文本
        Document doc = Jsoup.parse(html);
        //可以获取到html中<title>的值
        doc.title();

        //2.url
        try {
            //通过GET方式请求
            Document doc2 = Jsoup.connect(url).get();
            //通过POST方法请求
//          Document doc2 = Jsoup.connect(url).data("key","value").timeout(3000).post();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //3.本地html
        //获取本地html文件
        File file = new File(Environment.getExternalStorageDirectory()+"/index.html");
        //parse()方法参数解释:1.html文件  2.html的编码格式(本地html文件是什么编码就写什么编码)  3.当本地html文件中的图片或者链接采用的是相对路径时,就可以通过指定的baseUri替换路径的前缀。eg:.../baidu.png-->http://baidu.com/baidu.png
        try {
            Document doc3 = Jsoup.parse(file, "utf-8", "http://baidu.com");
        } catch (IOException e) {
            e.printStackTrace();
        }

        /*
         * 2.使用 Jsoup 解析并提取 HTML元素功能
         */
        Elements eles = doc.getElementsByTag("a");//将a标签的列表存储成元素集合
        for (Element link : eles) {
            //获取a标签中href的属性值
            String linkHref = link.attr("href");
            //获取a标签中的文本值
            String text = link.text();
        }
        //检索元素功能
        //检索html文件中的a标签并且就有href属性的a标签列表存储成元素集合
        Elements elements = doc.select("a[href]");
        //检索html文件中有img标签的.png格式的图片
        Elements elements2 = doc.select("img[src$=.png]");
        //检索出元素名为className的div标签的元素
        Element element3 = doc.select("div.className").first();

        /*
         * 3.使用 Jsoup 修改数据属性功能
         */
        //对元素名为className的div标签添加属性,属性名为key,属性值为value
        doc.select("div.className").attr("key","value");
        //为元素名为className的div标签添加属性类,添加的属性为:class="myclass"
        doc.select("div.className").addClass("myclass");
        //移除img标签的onClick属性
        doc.select("img").removeAttr("onClick");

        /*
         * 4.使用 Jsoup HTML 文档清理功能
         */
        String htmls = "";//不安全的一个html代码
        String safe = Jsoup.clean(htmls, Whitelist.basic());//用基本的白名单将不安全的html代码转换为安全的html

    }
}

使用Jsoup来实现复杂的Html列表解析:

实现效果:
使用 Jsoup 实现对某网站新闻列表的采集解析

package com.test.jsoupdemo;

import java.io.IOException;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.example.myxmltest.R;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

/**
 * 使用Jsoup解析HtmL新闻列表
 */
public class JsoupDemo extends Activity {
    private String url = "http://mobile.csdn.net/";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new Thread(new Runnable() {

            @Override
            public void run() {
                parseHtml();
            }
        }).start();;
    }
    //使用Jsoup解析html新闻列表
    private void parseHtml() {
        try {
            Document doc = Jsoup.connect(url).get();
            //将所有的新闻列表存储为元素的集合
            Elements elements = doc.select("div.unit");
            for (Element element : elements) {
                //获取每一条新闻的标题<h1>标签中的文本内容,因为每条新闻中只有一个h1,所以可以通过getElementsByTag("h1")获取到
                String title = element.getElementsByTag("h1").first().text();
                //获取每条新闻标题中的<h1>标签中的超链接
                String href = element.getElementsByTag("h1").first().getElementsByTag("a").first().attr("href");
                //获取每条新闻的新闻内容<dd>标签中的文本内容
//              String content = element.getElementsByTag("dd").first().text();
                Log.i("tag", title);
                Log.i("tag", href);
//              Log.i("tag", content);

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


}

原网页截图:
这里写图片描述

对应的网页源代码截图:
这里写图片描述

根据上图可以看出每条新闻的相同点:每条新闻的内容都是在<div class="unit">标签中。

这里写图片描述
通过上图可以发现每条新闻中只有一个<h1>标签。

运行结果截图:
这里写图片描述

<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>

版权声明:本文为博主原创文章,未经博主允许不得转载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值