w3c.dom 解析xml

本文介绍了一个使用Java DOM API操作XML文档的具体实例,包括读取、修改节点属性及值,添加新节点,并最终保存XML文件的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
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.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class DOMTool {
    
private String path;
    
private Document doc;
    
private Element root;

    
public Element getRoot() {
        
return root;
    }

    
public void setRoot(Element root) {
        
this.root = root;
    }

    
public Document getDoc() {
        
return doc;
    }

    
public void setDoc(Document doc) {
        
this.doc = doc;
    }

    
public String getPath() {
        
return path;
    }

    
public void setPath(String path) {
        
this.path = path;
    }

    
//根据xml文档建立Document对象
    public Document getDocument(String path)throws Exception{
        DocumentBuilderFactory dbf
=DocumentBuilderFactory.newInstance();
        DocumentBuilder db
=dbf.newDocumentBuilder();
        Document doc
=db.parse(new File(path));
        
return doc;
    }

    
//    获取node节点的值
    public String getNodeValue(Node node){
        Node firstChildNode
=node.getFirstChild();
        
short nodeType=firstChildNode.getNodeType();
        
if(nodeType==Node.TEXT_NODE){
            
return firstChildNode.getNodeValue();
        }

        
return null;
    }
    
    
//返回node的所有子节点
    public NodeList getChildNodes(Node node){
        
return node.getChildNodes();
    }

    
//设置node节点的值
    public void setNodeValue(Node node,String value){
        Node firstChildNode
=node.getFirstChild();
        
short nodeType=firstChildNode.getNodeType();
        
if(nodeType==Node.TEXT_NODE){
            firstChildNode.setNodeValue(value);
        }

    }

    
//在parentNode下追加子节点,该节点名为tagName,值为value
    public void appendChild(String tagName,String value,Node parentNode){
        Node newChild
=doc.createElement(tagName);
        Node child
=doc.createTextNode(value);
        newChild.appendChild(child);
        child
=doc.createTextNode(" ");
        parentNode.appendChild(child);
        parentNode.appendChild(newChild);
        parentNode.appendChild(child);
    }

    
//移除根节点
    public void removeRoot(){
        doc.removeChild(root);
    }

    
//如果不存在attrName属性,则创建该属性,并赋值为attrValue;如果存在,则直接赋值
    public void setNodeAttr(Element element,String attrName,String attrValue){
        element.setAttribute(attrName, attrValue);
    }

    
//返回element节点的attrName的属性值
    public String getNodeAttr(Element element,String attrName){
        
return element.getAttribute(attrName);
    }

    
//获取element的所有属性
    public NamedNodeMap getNodeAttrs(Node element){
        
return element.getAttributes();
    }

    
//移除element的attrName属性
    public void removeNodeAttr(Element element,String attrName){
        element.removeAttribute(attrName);
    }

    
//查看node节点的所有属性及其值
    public void nodeAttrsView(Node node){
        NamedNodeMap namedNodeMap
=node.getAttributes();
        
for(int i=0;i<namedNodeMap.getLength();i++){
            Node attr
=namedNodeMap.item(i);
            String attrName
=attr.getNodeName();
            String attrValue
=attr.getNodeValue();
            System.out.println(
"attr->value:["+attrName+":"+attrValue+"]");
        }

    }

    
//建立xml文档
    public void buildXmlFile()throws Exception{
        TransformerFactory tfactory
=TransformerFactory.newInstance();
        
try{
            Transformer transformer
=tfactory.newTransformer();
            DOMSource source
=new DOMSource(doc);
            StreamResult result
=new StreamResult(new File(path));
            transformer.setOutputProperty(
"encoding","UTF-8");
            transformer.transform(source, result);
        }
catch(TransformerConfigurationException e){}
    }

    
public static void main(String[] args)throws Exception{
        Element node
=null;
        DOMTool domTool
=new DOMTool();
        Document doc
=domTool.getDocument("a.xml");
        Element root
=doc.getDocumentElement();
        domTool.setDoc(doc);
        domTool.setPath(
"a.xml");
        domTool.setRoot(root);
        NodeList nodeList
=domTool.getChildNodes(root);
        
for(int i=0;i<nodeList.getLength();i++){
            
if(nodeList.item(i).getNodeType()==Node.ELEMENT_NODE){
                String nodeName
=nodeList.item(i).getNodeName();
                System.out.println(nodeName);
                
if(nodeName.equals("tlib-version")){
                    node
=(Element)nodeList.item(i);
                    domTool.setNodeValue(node, 
"2.0");
                    domTool.setNodeAttr(node, 
"value""3.0");
                    domTool.removeNodeAttr(node, 
"removeAttr");
                    domTool.setNodeAttr(node, 
"attrName""attrValue");
                    domTool.nodeAttrsView(node);
                }

            }

        }

        domTool.appendChild(
"insert_tag""insert_value", root);
//        domTool.removeRoot();
        domTool.buildXmlFile();
    }

}

另外root.getTextContent()可以得到root节点下所有文本值

可以通过if(child instanceof Element){....}来忽略空白字符

相检索到它们包含的文本字符串。这些文本字符串本身都包含在Text类型的子结点中。既然知道了这些Text结点是惟一的子元素,就可以用getFirstChild方法而不用再遍历一个NodeList,然后可以用getData方法检索存储在Text结点中的字符串。

for(int i=0;i<children.getLength();i++){
    Node child
=children.item(i);
    
if(child instanceof Element){
        Element childElement
=(Element)child;
        Text textNode
=(Text)childElement.getFirstChild();
        String text
=textNode.getData().trim();
    }

}

对getData的返回值调用trim方法是个好主意,如果xml文件的作者将起始和结束的标签放在不同的行上,比如:<size>
36
</size>

那么,解析器将会把所有的换行符和空格都包含到文本结点中,调用trim方法可以把实际数据前后的空白字符删掉

getNextSibling()得到下一个兄弟结点。
getPreviousSibling()得到上一个结点。
getParentNode()得到父结点

为了将DOCTYPE结点纳入输出,还需要将SYSTEM和PUBLIC标识符设置为输出属性:

Transformer t=TransformerFactory.newInstance().newTransformer();
t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,
"http://www.w3.org/TR/2000/CR-SVG-20000802/DTD/SVG-20000802.dtd");
t.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC,
"-//W3C/DTD SVG 20000802//EN");
t.transfom(
new DomSource(doc),new StreamResult(new FileOutputStream(f)));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值