JAVA-API Dom4J解析xml/OPML & Rome解析RSS & QRCode編碼解碼

一、DOM4J

DOM4J是 dom4j.org 出品的一個開源 XML 解析包。DOM4J應用於 Java 平臺,採用了 Java 集合框架並徹底支持 DOM,SAX 和 JAXP。java

DOM4J 使用起來很是簡單。只要你瞭解基本的 XML-DOM 模型,就能使用。node

Dom:把整個文檔做爲一個對象。ajax

DOM4J 最大的特點是使用大量的接口。它的主要接口都在org.dom4j裏面定義:json

Attribute框架

定義了 XML 的屬性。dom

Branchide

指可以包含子節點的節點。如XML元素(Element)和文檔(Docuemnts)定義了一個公共的行爲ui

CDATAthis

定義了 XML CDATA 區域google

CharacterData

是一個標識接口,標識基於字符的節點。如CDATA,Comment, Text.

Comment

定義了 XML 註釋的行爲

Document

定義了XML 文檔

DocumentType

定義 XML DOCTYPE 聲明

Element

定義XML 元素

ElementHandler

定義了Element 對象的處理器

ElementPath

被 ElementHandler 使用,用於取得當前正在處理的路徑層次信息

Entity

定義 XML entity

Node

爲dom4j中全部的XML節點定義了多態行爲

NodeFilter

定義了在dom4j 節點中產生的一個濾鏡或謂詞的行爲(predicate)

ProcessingInstruction

定義 XML 處理指令

Text

定義 XML 文本節點

Visitor

用於實現 Visitor模式

XPath

在分析一個字符串後會提供一個 XPath 表達式

 

二、XML文檔操做

讀取XML文檔:

讀寫XML文檔主要依賴於org.dom4j.io包,有DOMReader和SAXReader兩種方式。

SAXReader.read(File/URL);

private void ReadRss(String filePath) {

        File file = new File(filePath);

        if (!file.exists()) {
            // System.out.println("找不到【" + filePath + "】文件");
            // return;
            throw new RuntimeException("找不到【" + filePath + "】文件");
        }

        try {
            // 讀取並解析XML文檔
            // SAXReader就是一個管道,用一個流的方式,把xml文件讀出來
            SAXReader reader = new SAXReader();
            FileInputStream fis = new FileInputStream(file);
            // 下面的是經過解析xml字符串的
            Document doc = reader.read(fis);
            // 獲取根節點
            Element rootElt = doc.getRootElement(); // 獲取根節點
            // System.out.println("根節點:" + rootElt.getName()); // 拿到根節點的名稱

            // 獲取head/title節點
            Element titleElt = (Element) rootElt.selectSingleNode("head/title");

            // 獲取名稱
            String title = titleElt.getTextTrim();
                } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
}   

 

遍歷xml節點

Element類

getQName()

元素的QName對象

getNamespace()

元素所屬的Namespace對象

getNamespacePrefix()

元素所屬的Namespace對象的prefix

getNamespaceURI()

元素所屬的Namespace對象的URI

getName()

元素的local name

getQualifiedName()

元素的qualified name

getText()

元素所含有的text內容,若是內容爲空則返回一個空字符串而不是null

getTextTrim()

元素所含有的text內容,其中連續的空格被轉化爲單個空格,該方法不會返回null

attributeIterator()

元素屬性的iterator,其中每一個元素都是Attribute對象

attributeValue()

元素的某個指定屬性所含的值

elementIterator()

元素的子元素的iterator,其中每一個元素都是Element對象

element()

元素的某個指定(qualified name或者local name)的子元素

elementText()

元素的某個指定(qualified name或者local name)的子元素中的text信息

getParent

元素的父元素

getPath()

元素的XPath表達式,其中父元素的qualified name和子元素的qualified name之間使用"/"分隔

isTextOnly()

是否該元素只含有text或是空元素

isRootElement()

是否該元素是XML樹的根節點

 

Element bodyElt = (Element) rootElt.selectSingleNode("body");
// 獲取body節點下的outline節點
Iterator<?> iter = bodyElt.elementIterator("outline");
while (iter.hasNext()) {
            // 讀取outline節點下的全部outline信息,每條信息都是一條訂閱記錄
        Element TeamElt = (Element) iter.next();

        // 從新獲取分組名稱
        String title = TeamElt.attributeValue("title");
        String text = TeamElt.attributeValue("text");

        // 獲取body節點下的outline節點
        Iterator<?> iterRss = TeamElt.elementIterator("outline");
}

 

建立或修改XML

/**
     * 將document樹輸出到指定的文件
     * @param document document對象
     * @param filename 文件名
     * @return 布爾值
     */
    public static boolean doc2XmlFile(Document document, String filename) {
        boolean flag = true;
        try {
            XMLWriter writer = new XMLWriter( new OutputStreamWriter(new FileOutputStream(filename),"UTF-8"));
            writer.write(document);
            writer.close();
        } catch (Exception ex) {
            flag = false;
            ex.printStackTrace();
        }
            System.out.println(flag);
            return flag;
        }
    
    
    /**
     * 寫入操做
     * @param fileName
     */
    public static void write(String fileName){
        
        Document document=DocumentHelper.createDocument();//創建document對象,用來操做xml文件
        Element booksElement=document.addElement("books");//創建根節點
        booksElement.addComment("This is a test for dom4j ");//加入一行註釋
        Element bookElement=booksElement.addElement("book");//添加一個book節點
        bookElement.addAttribute("show","yes");//添加屬性內容
        Element titleElement=bookElement.addElement("title");//添加文本節點
        titleElement.setText("ajax in action");//添加文本內容
        try{
            
            XMLWriter writer=new XMLWriter(new FileWriter(new File(fileName))); 
            writer.write(document);
            writer.close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    
    
    /**
     * 修改XML文件
     */
    public static void modifyXMLFile() {
        String oldStr = "test.xml";
        String newStr = "test1.xml";
        Document document = null;
        //修改節點的屬性
        try {
            SAXReader saxReader = new SAXReader(); // 用來讀取xml文檔
            document = saxReader.read(new File(oldStr)); // 讀取xml文檔
            List list = document.selectNodes("/books/book/@show");// 用xpath查找節點book的屬性
            Iterator iter = list.iterator();
            while (iter.hasNext()) {
            Attribute attribute = (Attribute) iter.next();
            if (attribute.getValue().equals("yes"))
                attribute.setValue("no");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        //修改節點的內容
        try {
            SAXReader saxReader = new SAXReader(); // 用來讀取xml文檔
            document = saxReader.read(new File(oldStr)); // 讀取xml文檔
            List list = document.selectNodes("/books/book/title");// 用xpath查找節點book的內容
            Iterator iter = list.iterator();
            while (iter.hasNext()) {
            Element element = (Element) iter.next();
            element.setText("xxx");// 設置相應的內容
        }
        } catch (Exception e) {
            e.printStackTrace();
        }

        
        try {
            XMLWriter writer = new XMLWriter(new FileWriter(new File(newStr)));
            writer.write(document);
            writer.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

 

三、rome.jar 解析在線RSS地址

 用法見示例代碼,示例代碼解析了個人博客RSS,並將信息轉成JSON,用上json-lib.jar和它的支持庫。

import java.net.URL;
import java.util.List;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import com.sun.syndication.feed.synd.SyndCategory;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;

public class RomeReadRss {
    public void parseRss() {
        try {
            URL url = new URL("http://feed.cnblogs.com/blog/u/167721/rss");

            XmlReader reader = new XmlReader(url);
            SyndFeedInput input = new SyndFeedInput();
            SyndFeed feed = input.build(reader);

            // 獲得Rss新聞中子項列表
            List<SyndEntry> entries = feed.getEntries();

            JSONObject Root = new JSONObject();
            JSONArray List = new JSONArray();

            for (SyndEntry entry : entries) {
                JSONObject node = new JSONObject();
                node.put("title", entry.getTitle());
                node.put("link", entry.getLink());
                node.put("description", entry.getDescription().getValue());
                node.put("time", entry.getPublishedDate());
                node.put("author", entry.getAuthor());

                // 此標題所屬的範疇
                List categoryList = entry.getCategories();
                if (categoryList != null && categoryList.size() > 0) {
                    JSONArray cate = new JSONArray();
                    for (int m = 0; m < categoryList.size(); m++) {
                        SyndCategory category = (SyndCategory) categoryList
                                .get(m);
                        cate.add(category.getName());
                    }
                    node.put("category", cate);
                }
                List.add(node);
            }
            Root.put("List", List);
            System.out.println(Root.getJSONArray("List").getJSONObject(0)
                    .getString("title"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        RomeReadRss test = new RomeReadRss();
        test.parseRss();
    }
}

 

四、QRCode編碼解碼

先建立Google爲咱們提供的MatrixToImageWriter類,實現Google的BitMatrix與awt的BufferedImage之間的轉化,用來被Encode保存二維碼調用。

import com.google.zxing.common.BitMatrix;

import javax.imageio.ImageIO;
import java.io.File;
import java.io.OutputStream;
import java.io.IOException;
import java.awt.image.BufferedImage;

public final class MatrixToImageWriter {

    private static final int BLACK = 0xFF000000;
    private static final int WHITE = 0xFFFFFFFF;

    private MatrixToImageWriter() {
    }

    public static BufferedImage toBufferedImage(BitMatrix matrix) {
        int width = matrix.getWidth();
        int height = matrix.getHeight();
        BufferedImage image = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
            }
        }
        return image;
    }

    public static void writeToFile(BitMatrix matrix, String format, File file)
            throws IOException {
        BufferedImage image = toBufferedImage(matrix);
        if (!ImageIO.write(image, format, file)) {
            throw new IOException("Could not write an image of format "
                    + format + " to " + file);
        }
    }

    public static void writeToStream(BitMatrix matrix, String format,
            OutputStream stream) throws IOException {
        BufferedImage image = toBufferedImage(matrix);
        if (!ImageIO.write(image, format, stream)) {
            throw new IOException("Could not write an image of format "
                    + format);
        }
    }

}
View Code

再建立Google爲咱們提供的處理傳入的BufferedImage圖片灰度轉化和轉化爲Google LuminanceSource子類。

import com.google.zxing.LuminanceSource;

import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;

public final class BufferedImageLuminanceSource extends LuminanceSource {

    private final BufferedImage image;
    private final int left;
    private final int top;

    public BufferedImageLuminanceSource(BufferedImage image) {
        this(image, 0, 0, image.getWidth(), image.getHeight());
    }

    public BufferedImageLuminanceSource(BufferedImage image, int left, int top,
            int width, int height) {
        super(width, height);

        int sourceWidth = image.getWidth();
        int sourceHeight = image.getHeight();
        if (left + width > sourceWidth || top + height > sourceHeight) {
            throw new IllegalArgumentException(
                    "Crop rectangle does not fit within image data.");
        }

        for (int y = top; y < top + height; y++) {
            for (int x = left; x < left + width; x++) {
                if ((image.getRGB(x, y) & 0xFF000000) == 0) {
                    image.setRGB(x, y, 0xFFFFFFFF); // = white
                }
            }
        }

        this.image = new BufferedImage(sourceWidth, sourceHeight,
                BufferedImage.TYPE_BYTE_GRAY);
        this.image.getGraphics().drawImage(image, 0, 0, null);
        this.left = left;
        this.top = top;
    }

    @Override
    public byte[] getRow(int y, byte[] row) {
        if (y < 0 || y >= getHeight()) {
            throw new IllegalArgumentException(
                    "Requested row is outside the image: " + y);
        }
        int width = getWidth();
        if (row == null || row.length < width) {
            row = new byte[width];
        }
        image.getRaster().getDataElements(left, top + y, width, 1, row);
        return row;
    }

    @Override
    public byte[] getMatrix() {
        int width = getWidth();
        int height = getHeight();
        int area = width * height;
        byte[] matrix = new byte[area];
        image.getRaster().getDataElements(left, top, width, height, matrix);
        return matrix;
    }

    @Override
    public boolean isCropSupported() {
        return true;
    }

    @Override
    public LuminanceSource crop(int left, int top, int width, int height) {
        return new BufferedImageLuminanceSource(image, this.left + left,
                this.top + top, width, height);
    }

    @Override
    public boolean isRotateSupported() {
        return true;
    }

    @Override
    public LuminanceSource rotateCounterClockwise() {

        int sourceWidth = image.getWidth();
        int sourceHeight = image.getHeight();

        AffineTransform transform = new AffineTransform(0.0, -1.0, 1.0, 0.0,
                0.0, sourceWidth);

        BufferedImage rotatedImage = new BufferedImage(sourceHeight,
                sourceWidth, BufferedImage.TYPE_BYTE_GRAY);

        Graphics2D g = rotatedImage.createGraphics();
        g.drawImage(image, transform, null);
        g.dispose();

        int width = getWidth();
        return new BufferedImageLuminanceSource(rotatedImage, top, sourceWidth
                - (left + width), getHeight(), width);
    }

}
View Code

接下來是編碼與解碼

import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Hashtable;
import javax.imageio.ImageIO;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.Result;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

public class QRCode {
    public void encode(String contents, int width, int height, String imgPath) {
        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
        // 指定糾錯等級
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
        // 指定編碼格式
        hints.put(EncodeHintType.CHARACTER_SET, "GBK");
        try {
            BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,
                    BarcodeFormat.QR_CODE, width, height, hints);

            MatrixToImageWriter
                    .writeToFile(bitMatrix, "png", new File(imgPath));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public String decode(String imgPath) {
        try {
            BufferedImage image = ImageIO.read(new File(imgPath));
            if (image == null) {
                System.out.println("the decode image may be not exit.");
            }
            LuminanceSource source = new BufferedImageLuminanceSource(image);
            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));

            Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
            hints.put(DecodeHintType.CHARACTER_SET, "GBK");

            Result result = new MultiFormatReader().decode(bitmap, hints);
            return result.getText();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        String imgPath = "/Users/pcforsong/Desktop/QRCode.png";
        String contents = "歡迎訪問http://blog.kuangshi.info/博客站";
        QRCode handler = new QRCode();
        handler.encode(contents, 300, 300, imgPath);
        
        String decodeContent = handler.decode(imgPath);
        System.out.println("解碼內容:" + decodeContent);
    }
}
相關文章
相關標籤/搜索