2017年2月10日 星期五

DocumentBuilderFactory

※xml.xml

<?xml version="1.0" encoding="UTF-8"?>
<root>top1
    top2
    <first fa="f1" fb="1f">
        first-1
        <second1 sa="s1">aaa</second1>
        <second2>bbb</second2>
        <second3>ccc</second3>
    </first>
    top3
    <first fa="f2" fb="2f">
        first-2
        <second1 sa="s2">ddd</second1>
        <second2>eee</second2>
        <second3>fff</second3>
    </first>
    top4
    <first fa="f3" fb="3f">
        first-3
        <second1 sa="s3">ggg</second1>
        <second2>hhh</second2>
        <second3>iii</second3>
    </first>
</root>




※讀取元素

import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
    
public class Test {
    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse("src/main/java/xml.xml");
    
        NodeList nl = doc.getElementsByTagName("root");
        for (int i = 0; i < nl.getLength(); i++) {
            Node rootNode = nl.item(i);
            // System.out.println(rootNode.getNodeName());
            // System.out.println(rootNode.getNodeType());
            // System.out.println(rootNode.getNodeValue());
            // System.out.println(rootNode.getTextContent());
    
            Node fChildNode = rootNode.getFirstChild();
            // System.out.println(fChildNode.getNodeName());
            // System.out.println(fChildNode.getNodeType());
            // System.out.println(fChildNode.getNodeValue());
            // System.out.println(fChildNode.getTextContent());
    
            NodeList nodeList = rootNode.getChildNodes();
            for (int j = 0; j < nodeList.getLength(); j++) {
                Node nn = nodeList.item(j);
                System.out.println(nn.getNodeName());
                System.out.println(nn.getNodeType());
                System.out.println(nn.getNodeValue());
                System.out.println("------------------");
            }
        }
    }
}

※如果XML不是讀檔,而是傳來一個String,裡面是XML,可以用
InputStream in = new ByteArrayInputStream(xmlString.getBytes("UTF-8"));
再把in放在builder.parse裡即可

※Node.getNodeType()會回傳一個數字,API 寫的不清楚,要看Node.class的介面原碼才知道,
1是元素、2屬性、3文字,一般就用這三個

※要注意元素和元素之間的空,也算節點



※讀取屬性

import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
    
public class Test {
    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse("src/main/java/xml.xml");
    
        NodeList nl = doc.getElementsByTagName("root");
        for (int i = 0; i < nl.getLength(); i++) {
            Node rootNode = nl.item(i);
            NodeList nodeList = rootNode.getChildNodes();
            for (int j = 0; j < nodeList.getLength(); j++) {
                Node nn = nodeList.item(j);
                if (Node.ELEMENT_NODE == nn.getNodeType()) {
                    System.out.println(nn.getNodeName());
                    NamedNodeMap attrs = nn.getAttributes();
                    for (int k = 0; k < attrs.getLength(); k++) {
                        Node attr = attrs.item(k);
                        System.out.println(attr.getNodeName());
                        System.out.println(attr.getNodeValue());
                        System.out.println("------------------");
                    }
                    System.out.println("===================");
                }
            }
        }
    }
}

※nodeList回傳7,因為元素和元素之間也算節點,所以用Node.ELEMENT_NODE過濾掉
三個first算3個節點,還有first和first之間又有2個節點,最後first和root之間也有兩個節點,所以是7
最後的first和root雖然我沒寫文字,但還是節點

※讀到的text節點是有tab和換行的,不想要可以trim()掉



※寫檔

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
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.xml.sax.SAXException;
    
public class Test {
    public static void main(String[] args)
            throws ParserConfigurationException, SAXException, IOException, TransformerException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
    
        Document doc = builder.newDocument();
        // 新增元素
        Element root = doc.createElement("root");
        Element first = doc.createElement("first");
        Element second1 = doc.createElement("second1");
        Element second2 = doc.createElement("second2");
        Element second3 = doc.createElement("second3");
    
        // 元素的text
        root.appendChild(doc.createTextNode("top1" + System.getProperty("line.separator") + "\ttop2"));
        first.appendChild(doc.createTextNode("\tfirst-1"));
        second1.appendChild(doc.createTextNode("aaa"));
        second2.appendChild(doc.createTextNode("bbb"));
        second3.appendChild(doc.createTextNode("ccc"));
    
        // 元素組合
        root.appendChild(first);
        first.appendChild(second1);
        first.appendChild(second2);
        first.appendChild(second3);
    
        // 元素屬性
        first.setAttribute("fa", "f1");
        first.setAttribute("fb", "1f");
        second1.setAttribute("sa", "s1");
    
        doc.appendChild(root);
        DOMSource source = new DOMSource(doc);
    
        // 生成output
        File file = new File("D:/" + File.separator + "xml.xml");
        OutputStream out = new FileOutputStream(file, true);
        StreamResult result = new StreamResult(out);
    
        // 生成檔案
        TransformerFactory tFactory = TransformerFactory.newInstance();
        Transformer tf = tFactory.newTransformer();
        tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        tf.transform(source, result);
        out.close();
        System.out.println("XML已生成");
    }
}

※生出來的XML是不會排版的

※此例只是寫其中一個first而已

沒有留言:

張貼留言