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文檔主要依賴於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(); } }
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"); }
/** * 將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(); } }
用法見示例代碼,示例代碼解析了個人博客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(); } }
先建立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); } } }
再建立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); } }
接下來是編碼與解碼
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); } }