使用DOM生成XML文件

 
6.11  使用DOM生成XML文件
解析器通过在内存中建立和XML结构相对应的树状结构数据,使得应用程序可以方便地获得XML文件中的数据。JAXP也提供了使用内存中的树状结构数据建立一个XML文件的API,即使用解析器得到的Document对象建立一个新的XML文件。
1.Transformer对象
我们已经知道,解析器的parse方法将整个被解析的XML文件封装成一个Document节点返回,我们可以对Document节点进行修改,然后使用 Transformer对象将一个Document节点变换为一个XML文件。
即使解析器不调用parse方法,也可以得到一个Document节点。解析器通过调用newDocument()可得到一个Document节点,例如:
Document  document= builder.newDocument();
应用程序可通过修改这样的Document节点,然后使用 Transformer对象将一个Document节点变换为一个XML文件。
使用 Transformer对象将一个Document节点变换为一个XML文件需要经过如下  步骤。
使用javax.xml.transform包中的TransformerFactory类建立一个对象:
TransformerFactory transFactory=TransformerFactory. newInstance()
步骤 中得到的transFactory对象调用newTransformer()方法得到一个Transformer对象:
Transformer transformer=transFactory. newTransformer();
Transformer类在javax.xml.transform包中。
将被变换的Document对象封装到一个DOMSource对象中:
DOMSource  domSource=new DOMSource(document);
DOMSource类在javax.xml.transform.dom包中。
将变换得到XML文件对象封装到一个StreamResult对象中:
File file=new File("newXML.xml");
FileOutputStream out=new FileOutputStream(file);
StreamResult xmlResult=new StreamResult(out);
StreamResult类在javax.xml.transform.stream包中。
最后,Transformer 对象transformer 调用transform方法实施变换:
transformer.transform(domSource, xmlResult);
2.用于修改Document的常用方法
Node接口是Document的父接口,提供了许多用来修改、增加和删除节点的方法:
Node appendChild(Node newChild) 节点调用该方法可以向当前节点增加一个新的子节点,并返回这个新节点。
Node removeChild(Node oldChild) throws DOMException节点调用该方法删除参数指定的子节点,并返回被删除的子节点。
Node replaceChild(Node newChild, Node oldChild) 节点调用该方法可以替换子节点,并返回被替换的子节点。
Element接口本身除了从Node接口继承的方法外,也提供了用来增加节点的方法:
Attr removeAttributeNode(Attr oldAttr) 删除Element节点的属性。
void setAttribute(String name, String value)为Element节点增加新的属性及属性值,如果该属性已经存在,新的属性将替换旧的属性。
Text接口本身除了从Node接口继承的方法外,也提供了用来修改节点内容的方法:
Text replaceWholeText(String content) 替换当前Text节点的文本内容。
void appendData(String arg) 向当前Text节点尾加文本内容。
void insertData(int offset, String arg) 向当前Text节点插入文本内容,插入的位置由参数offset指定,即第offset个字符的后继位置。
void deleteData(int offset,int count) 删除当前节点的文本内容中的一部分。被删除的范围由参数offset和count指定,即从第offset个字符后续的count个字符。
void replaceData(int offset,int count, String arg)将当前Text节点中文本内容的一部分替换为参数arg指定的内容,被替换的范围由参数offset和count指定,即从第offset个字符后续的count个字符。
3.用DOM建立XML文件
在下面的例子10中,解析器解析一个XML文件:“cha6_10.xml”,然后修改Document对象,并用Transformer得到一个新的XML文件:“newXML.xml”。
例子10
Cha6_10.xml
<?xml  version="1.0"  encoding="UTF-8" ?>
<考试成绩单>
<高等数学>
<考生姓名>张三 </考生姓名>
<成绩> 89 </成绩>
</高等数学>
<高等数学>
<考生姓名> 李四 </考生姓名>
<成绩> 66 </成绩>
</高等数学>
</考试成绩单>
JAXPTen.java
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.*;
public class JAXPTen
{
public static void main(String args[])
{
ModifyNode modify=new ModifyNode();
try {
DocumentBuilderFactory  factory=
DocumentBuilderFactory. newInstance();
DocumentBuilder  builder= factory. newDocumentBuilder();
Document  document= builder. parse(new File("Cha6_10.xml")) ;
Element root=document.getDocumentElement() ;
NodeList nodeList=root.getChildNodes();
modify.modifyNode(nodeList);
TransformerFactory transFactory=TransformerFactory. newInstance();
Transformer transformer=transFactory. newTransformer();
DOMSource  domSource=new DOMSource(document);
File file=new File("newXML.xml");
FileOutputStream out=new FileOutputStream(file);
StreamResult xmlResult=new StreamResult(out);
transformer.transform(domSource, xmlResult);
}          
catch(Exception e)
{
System.out.println(e);
}
}
}
class  ModifyNode

int m=0;
public void modifyNode(NodeList nodeList)
{
int size=nodeList.getLength();
for(int k=0;k<size;k++)
{
Node node=nodeList.item(k);
if(node.getNodeType()==Node.TEXT_NODE)
{
Text textNode=(Text)node;
int length=textNode.getLength();
String str=textNode.getWholeText().trim();
try{
double d=Double.parseDouble(str);
if(d>=90&&d<=100)
textNode.insertData(length,"(优dd秀)");
else  if(d>=80&&d<90)
textNode.insertData(length,"(良好)");
else  if(d>=60&&d<80)
textNode.insertData(length,"(及格)");
else
textNode.insertData(length,"(不及格)");
}
catch(NumberFormatException ee)
{}                
}
if(node.getNodeType()==Node.ELEMENT_NODE)

Element elementNode=(Element)node;
String name=elementNode.getNodeName();
if(elementNode.hasChildNodes())
{
elementNode.setAttribute("考试性质","闭卷") ;
}
NodeList nodes=elementNode.getChildNodes();
modifyNode(nodes);
}
}
}
}
上述例子10得到的XML文件“newXML.xml”的内容如下:
newXML.xml
<?xml version="1.0" encoding="UTF-8"?><考试成绩单>
<高等数学 考试性质="闭卷">
<考生姓名 考试性质="闭卷">张三 </考生姓名>
<成绩 考试性质="闭卷"> 89 (良好)</成绩>
</高等数学>
<高等数学 考试性质="闭卷">
<考生姓名 考试性质="闭卷"> 李四 </考生姓名>
<成绩 考试性质="闭卷"> 66 (及格)</成绩>
</高等数学>
</考试成绩单>
上述例子10中的DOM解析器利用已知的XML文件产生一个Document对象,然后对内存中的Document对象修改后,再生成一个新的XML文件。在下面的例子11中,DOM解析器调用newDocument()得到一个Document对象,“JavaEleven.java”产生的XML文件是“火车时刻表.xml”,用浏览器打开它的效果如图6.12所示。
图6.12  用DOM生成的XML文件

例子11
JAXPEleven.java
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.*;
public class JAXPEleven
{
public static void main(String args[])
{
try {
String  train[]={"T126次","K256次","L345次"},
type[] ={"特快","普快","临客"},
startTime []={"18:36","22:56","10:12"};
DocumentBuilderFactory  factory=
DocumentBuilderFactory. newInstance();
DocumentBuilder  builder= factory. newDocumentBuilder();
Document  document= builder.newDocument();
document.setXmlVersion("1.0");
Element 火车时刻表=document.createElement("火车时刻表");
document.appendChild(火车时刻表);
for(int k=1;k<=train.length;k++)
{
火车时刻表.appendChild(document.createElement("车次"));
}
NodeList  nodeList=document.getElementsByTagName("车次");
int size=nodeList.getLength();
for(int k=0;k<size;k++)
{
Node node=nodeList.item(k);
if(node.getNodeType()==Node.ELEMENT_NODE)

Element elementNode=(Element)node;
elementNode.setAttribute("类别", type[k]);
elementNode.appendChild(document.createElement("名字"));
elementNode.appendChild(document.createElement("开车时间"));
}
}
nodeList=document.getElementsByTagName("名字");
size=nodeList.getLength();
for(int k=0;k<size;k++)
{
Node node=nodeList.item(k);
if(node.getNodeType()==Node.ELEMENT_NODE)

Element elementNode=(Element)node;
elementNode.appendChild(document.createTextNode(train[k]));
}
}
nodeList=document.getElementsByTagName("开车时间");
size=nodeList.getLength();
for(int k=0;k<size;k++)
{
Node node=nodeList.item(k);
if(node.getNodeType()==Node.ELEMENT_NODE)

Element elementNode=(Element)node;
elementNode.appendChild(document.createTextNode
(startTime[k]));
}
}
TransformerFactory transFactory=TransformerFactory.newInstance();
Transformer transformer=transFactory.newTransformer();
DOMSource  domSource=new DOMSource(document);
File file=new File("火车时刻表.xml");
FileOutputStream out=new FileOutputStream(file);
StreamResult xmlResult=new StreamResult(out);
transformer.transform(domSource, xmlResult);
}
catch(Exception e)
{
System.out.println(e);
}

}       
}

你可能感兴趣的:(xml)