zoukankan      html  css  js  c++  java
  • JAVA-API Dom4J解析xml/OPML & Rome解析RSS & QRCode编码解码

    1、DOM4J

    DOM4J是 dom4j.org 出品的一个开源 XML 解析包。DOM4J应用于 Java 平台,采用了 Java 集合框架并完全支持 DOM,SAX 和 JAXP。

    DOM4J 使用起来非常简单。只要你了解基本的 XML-DOM 模型,就能使用。

    Dom:把整个文档作为一个对象。

    DOM4J 最大的特色是使用大量的接口。它的主要接口都在org.dom4j里面定义:

    Attribute

    定义了 XML 的属性。

    Branch

    指能够包含子节点的节点。如XML元素(Element)和文档(Docuemnts)定义了一个公共的行为

    CDATA

    定义了 XML CDATA 区域

    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 表达式

    2、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();
            }
        }

    3、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();
        }
    }

    4、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);
        }
    }
  • 相关阅读:
    尽可能的降低重复劳动——模板策略
    一个CSS上中下三行三列结构的Div布局
    程序员那些悲催的事儿
    给NSString增加Java风格的方法
    DIV和table页面布局的区别和联系
    cocos2d播放雪花
    时间复杂度和空间复杂度2 数据结构和算法04
    OD使用教程4 调试篇04|解密系列
    OD使用教程5 调试篇05|解密系列
    PE结构简图
  • 原文地址:https://www.cnblogs.com/updateofsimon/p/3624716.html
Copyright © 2011-2022 走看看