码迷,mamicode.com
首页 > 其他好文 > 详细

xml文件解析基础和签名

时间:2015-05-13 21:53:59      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:xml   基础   签名   

0. 前言

1.xml文件的解析

1.1 基本的jdk解析xml的原始api解析


  • 声明

  • 1.以下代码块要放到一个类中才能运行
  • dom类型为:org.w3c.dom.*
  • 解析的包:javax.xml.*

1.1.1 输出所xml所有节点内容

/**
 * 如同js一样的获取节点内容
 */
public static void listNl(NodeList nl) {
    int len = nl.getLength();
    for (int i = 0; i < len; i++) {
        Element eltStudent = (Element) nl.item(i);
        Node eltName = eltStudent.getElementsByTagName("name").item(0);
        Node eltAge = eltStudent.getElementsByTagName("age").item(0);
        String name = eltName.getFirstChild().getNodeValue();
        String age = eltAge.getFirstChild().getNodeValue();
        System.out.print("姓名:");
        System.out.println(name);
        System.out.print("年龄:");
        System.out.println(age);
        System.out.println("------------------------");
    }
}
@Test
/**
 * 输出所xml所有节点内容
 */
// 示例地址:http://it.chinawin.net/softwaredev/article-16023.html
public void test_ParseXml1Net_01() throws Exception {
    String path = "D:\\workspace\\java_base\\src\\hw\\learn\\simple\\xml\\student.xml";
    FileInputStream fis = new FileInputStream(new File(path));
    DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = f.newDocumentBuilder();
    Document doc = builder.parse(fis);
    NodeList nl = doc.getElementsByTagName("student");
    listNl(nl);
}

1.1.2 将字符串转化为xml文件

/**
 * 将字符串转化为xml文件
 *//***/
@Test
public void test_String2Xml() throws Exception {
    // String xmlStr = new String("ASDFADADSD");//报错:[Fatal Error] :1:1: 前言中不允许有内容。
    String xmlStr = new String("<?xml version=\"1.0\" encoding=\"GB2312\"?><students><student sn=\"01\"><name>张三</name><age>18</age></student><student sn=\"02\"><name>李四</name><age>20</age></student></students>");
    StringReader sr = new StringReader(xmlStr);
    InputSource is = new InputSource(sr);
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document doc = builder.parse(is);
    System.out.println(doc.getClass());//com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl
}

1.1.3 将xml文件转化为字符串

/**
 * 读取本地文件xml文件为Document对象
 */
public static Document test_readXml() throws Exception {
    String path = "D:\\workspace\\java_base\\src\\hw\\learn\\simple\\xml\\student.xml";
    FileInputStream fis = new FileInputStream(new File(path));
    DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = f.newDocumentBuilder();
    Document doc = builder.parse(fis);
    System.out.println(doc);// ★★[#document: null]注意这里不是打印出来xml文件内容,并不代表没有读到xml文件
    return doc;
}
@Test
/**
 * 将xml文件转化为字符串
 */
public void test_Xml2String() throws Exception {
    Document doc = this.test_readXml();
    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer t = tf.newTransformer();
    t.setOutputProperty("encoding", "UTF-8");
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    t.transform(new DOMSource(doc), new StreamResult(bos));
    String xmlStr = bos.toString();
    System.out.println(xmlStr);
}

1.2 使用dom4解析xml


  • 声明

  • 以下代码块要放到一个类中才能运行
  • dom类型和解析的包为:org.dom4j.*
  • ★注意:javax.xml.parsers中的和dom4j中的两种形式的Document不能转换

1.2.1将String转换为Dom4j的Document类对象

/**
 * 所以在应用时只能用一套xml解析方案,不能交替使用,否则报:ClassCastException异常
 * dom4j具体细节操作:参见http://www.cnblogs.com/liuling/archive/2013/02/05/dom4jxml.html
 *//***/
@Test
public void test_String2Xml_dom4j() throws DocumentException {
    String path = "D:\\workspace\\java_base\\src\\hw\\learn\\simple\\xml\\student.xml";
    String xmlStr = new String("<?xml version=\"1.0\" encoding=\"GB2312\"?><students><student sn=\"01\"><name>张三</name><age>18</age></student><student sn=\"02\"><name>李四</name><age>20</age></student></students>");
    Document document = DocumentHelper.parseText(xmlStr);// 必须引入dom4j的Document
}

1.2.2 最普通的方法得到xml文件信息

@Test
/**
 * 方法1:将xml文件看成普通文本文件输出字符信息
 */
public void test_OrdTextReadXml() throws Exception {
    String path = "D:\\workspace\\java_base\\src\\hw\\learn\\simple\\xml\\student.xml";
    File f = new File(path);
    InputStream in = new FileInputStream(f);
    byte[] b = new byte[1024];
    in.read(b);
    in.close();
    System.out.println(new String(b));
}

@Test
/**
 * ★★方法2:解析后读取xml文件中所有节点信息,
 */
public void test_Xml2String_dom4j() throws Exception {
    SAXReader sr = new SAXReader();// 获取读取xml的对象。
    String path = "D:\\workspace\\java_base\\src\\hw\\learn\\simple\\xml\\student.xml";
    Document doc = sr.read(path);// 得到xml所在位置。然后开始读取。并将数据放入doc中
    Element el_root = doc.getRootElement();// 向外取数据,获取xml的根节点。
    Iterator it = el_root.elementIterator();// 从根节点下依次遍历,获取根节点下所有子节点
    while (it.hasNext()) {// 遍历该子节点
        Object o = it.next();// 再获取该子节点下的子节点
        Element el_row = (Element) o;
        String s = el_row.getText();
        Iterator it_row = el_row.elementIterator();
        while (it_row.hasNext()) {// 遍历节点
            Element el_ename = (Element) it_row.next();// 获取该节点下的所有数据。
            System.out.println(el_ename.getText());
        }
    }
}

@Test
/**
 * 方法三:使用elements方法进行xml的读取,相当于条件查询,可以根据不同的节点,利用for循环查询该节点下所有的数据。
 * 依据不同的xml文件而定
 */
public void test_ByElement() throws Exception {
    SAXReader sr = new SAXReader();// 获取读取方式
    String path = "D:\\workspace\\java_base\\src\\hw\\learn\\simple\\xml\\student.xml";
    Document doc = sr.read(path);// 读取xml文件,并且将数据全部存放到Document中
    Element root = doc.getRootElement();// 获取根节点
    List list = root.elements("student");// 根据根节点,将根节点下 student中的所有数据放到list容器中。
    for (Object obj : list) {// 这种遍历方式,是jdk1.5以上的版本支持的遍历方式
        Element row = (Element) obj;
        List list_name = row.elements("name");// 获取name节点下所有的内容,存入list_row容器中
        for (Object objempno : list_name) {
            Element el_empno = (Element) objempno;
            System.out.println(el_empno.getName() + ": " + el_empno.getText());// 获取节点下的数据。
        }
    }
}

@Test
/**
 * 方法四:使用selectNodes()方法
 */
public void test_bySelectNode() throws Exception {
    String elementpath = new String("name");// 使用selectNodes获取所要查询xml的节点。
    SAXReader sr = new SAXReader();
    String path = "D:\\workspace\\java_base\\src\\hw\\learn\\simple\\xml\\student.xml";
    Document doc = sr.read(path);
    List list = doc.selectNodes(elementpath);
    for (Object obj : list) {// 遍历节点,获取节点内数据。
        Element el = (Element) obj;
        System.out.println(el.getText());
    }
}

2. xml签名

xml作为一种通用跨平台的数据传输的方式,其安全性也受到重视,很多应用或商家在用xml文件之间传输信息时通常要对xml文件进行签名,以确定数据的完整性,以及防篡改。下面是在工作中遇到的签名xml文件的一种方式。

public class SignXml {
    // 参考文档:http://www.javacodegeeks.com/2013/10/xml-security-with-digital-signature-in-java.html
    /**
     * @param doc 待签名的xml文档
     * @param privateKey  用于对xml签名的私钥
     * @return 已签名的xml文档
     */
    public static Document signXmlDoc(Document doc, PrivateKey privateKey) throws Exception {
        // 创建XML签名工厂
        XMLSignatureFactory xmlSigFactory = XMLSignatureFactory.getInstance("DOM");
        DOMSignContext domSignCtx = new DOMSignContext(privateKey, doc.getDocumentElement());
        System.out.println(domSignCtx);
        javax.xml.crypto.dsig.Reference ref = null;
        SignedInfo signedInfo = null;
        try {
            ref = xmlSigFactory.newReference("#CUSTINFOREQ", xmlSigFactory.newDigestMethod(DigestMethod.SHA1, null), Collections.singletonList(xmlSigFactory.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)), null, null);
            signedInfo = xmlSigFactory.newSignedInfo(xmlSigFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null), xmlSigFactory.newSignatureMethod(SignatureMethod.RSA_SHA1, null), Collections.singletonList(ref));
            System.out.println(signedInfo);
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
        KeyInfo ki = null;
        // 创建新的XML签名
        XMLSignature xmlSignature = xmlSigFactory.newXMLSignature(signedInfo, ki);
        try {
            // 对文档签名
            xmlSignature.sign(domSignCtx);
            // ★打印出来xml文档:查看签名信息!【org.dom.Document->String】
            System.out.println("#Begin:get signedXmlDoc********************************");
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer t = tf.newTransformer();
            t.setOutputProperty("encoding", "GB23121");
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            t.transform(new DOMSource(doc), new StreamResult(bos));
            String xmlStr = bos.toString();
            System.out.println(xmlStr);
            System.out.println("#End:get signedXmlDoc********************************");
            return doc;
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
    }
}

xml文件解析基础和签名

标签:xml   基础   签名   

原文地址:http://blog.csdn.net/heweirun_2014/article/details/45699409

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!