标签:des java 使用 io 文件 for 问题 ar
见摘要、见代码注释,其他话不多说:
DTD文档:
<?xml version="1.0" encoding="UTF-8"?> <!ELEMENT SwordLibrary (Sword*)> <!ELEMENT Sword (SwordName,Price,Attack)> <!ELEMENT SwordName (#PCDATA)> <!ELEMENT Price (#PCDATA)> <!ELEMENT Attack (#PCDATA)> <!ATTLIST Sword sno CDATA #REQUIRED> <!ATTLIST Price type CDATA #IMPLIED> <!ATTLIST Attack factor CDATA "1.0">
Xml文档:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE SwordLibrary SYSTEM "SwordTypeDefinition.dtd"> <SwordLibrary> <Sword sno="s1"> <SwordName>欢欣之刃</SwordName> <Price>1000</Price> <Attack factor="1.0">10</Attack> </Sword> <Sword sno="s2"> <SwordName>夜叉</SwordName> <Price>2050</Price> <Attack factor="2.0">30</Attack> </Sword> <Sword sno="s3"> <SwordName>魔棒</SwordName> <Price type="Dollar">200</Price> <Attack factor="1.0">0</Attack> </Sword> </SwordLibrary>
java代码:
package JavaLeaner.XmlTest;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class XmlDemo3 {
/*
* 强制执行dtd校验,但是是在运行时
*
*/
@Test
public void Test1() throws ParserConfigurationException, SAXException, IOException
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//强制执行dtd校验,但是是在运行时
factory.setValidating(true);
DocumentBuilder docDuilder = factory.newDocumentBuilder();
Document doc = docDuilder.parse("src/JavaLeaner/XmlTest/SwordLib.xml");
/*
* 使用DocumentBuilderFactory的setValidating(true)方法可以将dtd校验在运行阶段执行
* 可以正常编译,但在会爬出异常:(异常被声明,所以JUnit的运行条颜色是绿色)
* Warning: validation was turned on but an org.xml.sax.ErrorHandler was not
set, which is probably not what is desired. Parser will use a default
ErrorHandler to print the first 10 errors. Please call
the ‘setErrorHandler‘ method to fix this.
Error: URI=file:///home/XXXX/workspace/Learning/HelloWorld/src/JavaLeaner/XmlTest/SwordLib.xml Line=9: 需要属性 "sno", 并且必须为元素类型 "Sword" 指定该属性。
*/
//单步执行抛出异常的语句在docDuilder.parse
}
/*
* 改:
* 修改修改已有标签内容和属性
* 注意:属性如果有则是修改,无则会添加,使用的都是setAttribute
*/
@Test
public void Test2() throws ParserConfigurationException, SAXException, IOException, TransformerException
{
String fileName="src/JavaLeaner/XmlTest/SwordLib.xml";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//factory.setValidating(true);
DocumentBuilder docDuilder = factory.newDocumentBuilder();
Document doc = docDuilder.parse(fileName);
//Element rootElement = doc.getDocumentElement();
Element rootElement = (Element)doc.getElementsByTagName("SwordLibrary").item(0);
NodeList list= rootElement.getElementsByTagName("Price");//由此可以看出,这里的搜索不仅仅是子元素,也可以是孙子元素
for(int i=0;i<list.getLength();i++)
{
Element e = (Element)list.item(i);
//更改或者添加属性设置
e.setAttribute("type", "yan");
//更改元素内容
e.setTextContent("0");
}
//将更改后的文档对象写回xml文件
TransformerFactory transformerfactory = TransformerFactory.newInstance();
Transformer tf=transformerfactory.newTransformer();
//tf.transform(new DOMSource(doc.getDoctype()),new StreamResult(new FileOutputStream(fileName)));
//注意:如果想让xml中的Doctype标签不丢失,必须在转换类对象进行输出属性设置。
//下面这句由于对xml的Dctype设置的dtd声明为public的情况
//tf.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_PUBLIC, doc.getDoctype().getPublicId());
//下面这句由于对xml的Dctype设置的dtd声明为System的情况
tf.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId());
tf.transform(new DOMSource(doc),new StreamResult(new FileOutputStream(fileName)));
/* <?xml version="1.0" encoding="UTF-8" standalone="no"?><SwordLibrary>
<Sword sno="s1">
<SwordName>欢欣之刃</SwordName>
<Price type="yan">0</Price>
<Attack factor="1.0">10</Attack>
</Sword>
<Sword sno="s2">
<SwordName>夜叉</SwordName>
<Price type="yan">0</Price>
<Attack factor="2.0">30</Attack>
</Sword>
<Sword sno="s3">
<SwordName>魔棒</SwordName>
<Price type="yan">0</Price>
<Attack factor="1.0">0</Attack>
</Sword>
</SwordLibrary>
*/
}
/*
*
* 追加节点
*
*/
@Test
public void Test3() throws ParserConfigurationException, SAXException, IOException, TransformerException
{
String fileName="src/JavaLeaner/XmlTest/SwordLib.xml";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(true);
DocumentBuilder docDuilder = factory.newDocumentBuilder();
Document doc = docDuilder.parse(fileName);
//用文档对象创建元素
Element eSword=doc.createElement("Sword");
eSword.setAttribute("sno", "s4");
//用文档对象创建子元素
Element esname=doc.createElement("SwordName");
Element esprice=doc.createElement("Price");
Element esattack=doc.createElement("Attack");
//发现问题后,补上的
esname.setTextContent("散华");
esprice.setTextContent("2050");
esattack.setTextContent("30");
//将子元素添加到元素里
eSword.appendChild(esname);
eSword.appendChild(esprice);
eSword.appendChild(esattack);
//将元素添加到文档里,及根元素
doc.getDocumentElement().appendChild(eSword);
//注意: doc.appendChild(eSword);是错误的
//eSword应该在根元素SwordLibrary下
System.out.println("doc.getDocumentElement(): "+doc.getDocumentElement().getNodeName());
//将更改后的文档对象写回xml文件
TransformerFactory transformerfactory = TransformerFactory.newInstance();
Transformer tf=transformerfactory.newTransformer();
//注意:如果想让xml中的Doctype标签不丢失,必须在转换类对象进行输出属性设置。
//下面这句由于对xml的Dctype设置的dtd声明为public的情况
//tf.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_PUBLIC, doc.getDoctype().getPublicId());
//下面这句由于对xml的Dctype设置的dtd声明为System的情况
tf.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId());
tf.transform(new DOMSource(doc),new StreamResult(new FileOutputStream(fileName)));
/*
*
*
*
* Warning: validation was turned on but an org.xml.sax.ErrorHandler was
* not set, which is probably not what is desired. Parser will use a
* default ErrorHandler to print the first 10 errors. Please call the
* ‘setErrorHandler‘ method to fix this. Error:
* URI=file:///home/neil/workspace
* /Learning/HelloWorld/src/JavaLeaner/XmlTest/SwordLib.xml Line=1:
* 文档根元素 "SwordLibrary" 必须匹配 DOCTYPE 根 "null"。 Error:
* URI=file:///home/neil
* /workspace/Learning/HelloWorld/src/JavaLeaner/XmlTest/SwordLib.xml
* Line=1: 文档无效: 找不到语法。 doc.getDocumentElement(): SwordLibrary
*
*
* <?xml version="1.0" encoding="UTF-8" standalone="no"?><SwordLibrary>
* <Sword sno="s1"> <SwordName>欢欣之刃</SwordName> <Price>1000</Price>
* <Attack factor="1.0">10</Attack> </Sword> <Sword sno="s2">
* <SwordName>夜叉</SwordName> <Price>2050</Price> <Attack
* factor="2.0">30</Attack> </Sword> <Sword sno="s3">
* <SwordName>魔棒</SwordName> <Price type="Dollar">200</Price> <Attack
* factor="1.0">0</Attack> </Sword> <Sword
* sno="s4"><SwordName/><Price/><Attack/></Sword></SwordLibrary>
*/
}
/*
* 实验
* 在之前的实验中发现,虽然xml被成功更改,但是Doctype属性在文档对象写回文件后发生了丢失的现象
* 这是因为DocType写回xml文件时,需要单独设置属性setOutputProperty
*/
@Test
public void Test4() throws ParserConfigurationException, SAXException, IOException, TransformerException
{
{
String fileName="src/JavaLeaner/XmlTest/SwordLib.xml";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//factory.setValidating(true);
DocumentBuilder docDuilder = factory.newDocumentBuilder();
Document doc = docDuilder.parse(fileName);
/* DocumentType doctype = doc.getDoctype();
String docText = doctype.getName();
System.out.println("DocumentType:" + docText);*/
TransformerFactory transformerfactory = TransformerFactory.newInstance();
Transformer tf=transformerfactory.newTransformer();
if(doc==null)
{
System.out.println("doc is null");
return;
}
if(doc.getDoctype()==null)
{
System.out.println("DocumentType is null");
return;
}
//注意:如果想让xml中的Doctype标签不丢失,必须在转换类对象进行输出属性设置。
//下面这句由于对xml的Dctype设置的dtd声明为public的情况
//tf.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_PUBLIC, doc.getDoctype().getPublicId());
//下面这句由于对xml的Dctype设置的dtd声明为System的情况
tf.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId());
//doc.setXmlStandalone(xmlStandalone);
DOMSource domSource=new DOMSource(doc);
tf.transform(domSource,new StreamResult(new FileOutputStream(fileName)));
/* DocumentType doctype2 = doc.getDoctype();
if (doctype2 != null) {
String docText2 = doctype2.getName();
System.out.println("DocumentType:" + docText2);
} else {
System.out.println("DocumentType is null");
}*/
}
{
String fileName="src/JavaLeaner/XmlTest/SwordLib.xml";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//factory.setValidating(true);
DocumentBuilder docDuilder = factory.newDocumentBuilder();
Document doc = docDuilder.parse(fileName);
System.out.println("getXmlStandalone:" + (doc.getXmlStandalone()?1:0));
DocumentType doctype = doc.getDoctype();
if (doctype != null) {
String docText = doctype.getName();
System.out.println("DocumentType:" + docText);
} else {
System.out.println("DocumentType is null");
}
}
}
/*
* 删除节点:方法1://从爸爸找起,逐一审查儿子
*/
@Test
public void Test5() throws ParserConfigurationException, SAXException, IOException, TransformerException
{
String fileName="src/JavaLeaner/XmlTest/SwordLib.xml";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(true);
DocumentBuilder docDuilder = factory.newDocumentBuilder();
Document doc = docDuilder.parse(fileName);
//从爸爸找起,逐一审查儿子
NodeList list = doc.getElementsByTagName("Sword");
for (int i = 0; i < list.getLength(); i++) {
Element eSword = (Element) list.item(i);
if (eSword.getElementsByTagName("SwordName").getLength() >= 0) {
Element ename = (Element) eSword.getElementsByTagName(
"SwordName").item(0);
if ("散华".equals(ename.getTextContent())) {
((Element)doc.getDocumentElement()).removeChild(eSword);
System.out.println("deleted!");
}
}
}
//将更改后的文档对象写回xml文件
TransformerFactory transformerfactory = TransformerFactory.newInstance();
Transformer tf=transformerfactory.newTransformer();
//如果想让xml中的Doctype标签不丢失,必须在转换类对象进行输出属性设置。
tf.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId());
tf.transform(new DOMSource(doc),new StreamResult(new FileOutputStream(fileName)));
}
/*
* 删除节点:方法2://直接找当事人,然后爷爷打爸爸。(看不懂吗?看看代码就知道了)
*/
@Test
public void Test6() throws ParserConfigurationException, SAXException, IOException, TransformerException
{
String fileName="src/JavaLeaner/XmlTest/SwordLib.xml";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(true);
DocumentBuilder docDuilder = factory.newDocumentBuilder();
Document doc = docDuilder.parse(fileName);
NodeList list = doc.getElementsByTagName("SwordName");
for (int i = 0; i < list.getLength(); i++) {
Element ename = (Element) list.item(i);
if("散华".equals(ename.getTextContent()))
{
//典型的爷爷打爸爸
ename.getParentNode().getParentNode().removeChild(ename.getParentNode());
System.out.println("deleted!");
}
}
//将更改后的文档对象写回xml文件
TransformerFactory transformerfactory = TransformerFactory.newInstance();
Transformer tf=transformerfactory.newTransformer();
//如果想让xml中的Doctype标签不丢失,必须在转换类对象进行输出属性设置。
tf.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId());
tf.transform(new DOMSource(doc),new StreamResult(new FileOutputStream(fileName)));
}
}
Java学习之Xml系列三:dtd校验、改、增、删,布布扣,bubuko.com
标签:des java 使用 io 文件 for 问题 ar
原文地址:http://my.oschina.net/u/1156339/blog/296945