我必须读写XML文件。使用Java读取和写入XML文件的最简单方法是什么?如何读取和写入XML文件?
回答
这里是一个快速DOM的例子,显示了如何读取和写入其DTD一个简单的XML文件:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE roles SYSTEM "roles.dtd">
<roles>
<role1>User</role1>
<role2>Author</role2>
<role3>Admin</role3>
<role4/>
</roles>
和DTD:
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT roles (role1,role2,role3,role4)>
<!ELEMENT role1 (#PCDATA)>
<!ELEMENT role2 (#PCDATA)>
<!ELEMENT role3 (#PCDATA)>
<!ELEMENT role4 (#PCDATA)>
首次进口这些:
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import org.xml.sax.*;
import org.w3c.dom.*;
以下是您需要的几个变量:
这里是一个读者(字符串XML是XML文件的名称):
public boolean readXML(String xml) {
rolev = new ArrayList<String>();
Document dom;
// Make an instance of the DocumentBuilderFactory
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
// use the factory to take an instance of the document builder
DocumentBuilder db = dbf.newDocumentBuilder();
// parse using the builder to get the DOM mapping of the
// XML file
dom = db.parse(xml);
Element doc = dom.getDocumentElement();
role1 = getTextValue(role1, doc, "role1");
if (role1 != null) {
if (!role1.isEmpty())
rolev.add(role1);
}
role2 = getTextValue(role2, doc, "role2");
if (role2 != null) {
if (!role2.isEmpty())
rolev.add(role2);
}
role3 = getTextValue(role3, doc, "role3");
if (role3 != null) {
if (!role3.isEmpty())
rolev.add(role3);
}
role4 = getTextValue(role4, doc, "role4");
if (role4 != null) {
if (!role4.isEmpty())
rolev.add(role4);
}
return true;
} catch (ParserConfigurationException pce) {
System.out.println(pce.getMessage());
} catch (SAXException se) {
System.out.println(se.getMessage());
} catch (IOException ioe) {
System.err.println(ioe.getMessage());
}
return false;
}
在这里,一个作家:
public void saveToXML(String xml) {
Document dom;
Element e = null;
// instance of a DocumentBuilderFactory
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
// use factory to get an instance of document builder
DocumentBuilder db = dbf.newDocumentBuilder();
// create instance of DOM
dom = db.newDocument();
// create the root element
Element rootEle = dom.createElement("roles");
// create data elements and place them under root
e = dom.createElement("role1");
e.appendChild(dom.createTextNode(role1));
rootEle.appendChild(e);
e = dom.createElement("role2");
e.appendChild(dom.createTextNode(role2));
rootEle.appendChild(e);
e = dom.createElement("role3");
e.appendChild(dom.createTextNode(role3));
rootEle.appendChild(e);
e = dom.createElement("role4");
e.appendChild(dom.createTextNode(role4));
rootEle.appendChild(e);
dom.appendChild(rootEle);
try {
Transformer tr = TransformerFactory.newInstance().newTransformer();
tr.setOutputProperty(OutputKeys.INDENT, "yes");
tr.setOutputProperty(OutputKeys.METHOD, "xml");
tr.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
tr.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "roles.dtd");
tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
// send DOM to file
tr.transform(new DOMSource(dom),
new StreamResult(new FileOutputStream(xml)));
} catch (TransformerException te) {
System.out.println(te.getMessage());
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
}
} catch (ParserConfigurationException pce) {
System.out.println("UsersXML: Error trying to instantiate DocumentBuilder " + pce);
}
}
getTextValue是在这里:
private String getTextValue(String def, Element doc, String tag) {
String value = def;
NodeList nl;
nl = doc.getElementsByTagName(tag);
if (nl.getLength() > 0 && nl.item(0).hasChildNodes()) {
value = nl.item(0).getFirstChild().getNodeValue();
}
return value;
}
添加一些accessor和mutators,你就完成了!
上面的答案只涉及DOM解析器(通常读取内存中的整个文件并解析它,对于大文件来说是一个问题),您可以使用SAX解析器,该解析器使用更少的内存并且速度更快这取决于你的代码)。
SAX解析器回调一些函数,当它找到元素的开始,元素的结尾,属性,元素之间的文本等,所以它可以解析文档,同时你得到你需要的东西。
一些示例代码:
http://www.mkyong.com/java/how-to-read-xml-file-in-java-sax-parser/
使用JAXB编写XML(Java体系XML绑定):
http://www.mkyong.com/java/jaxb-hello-world-example/
package com.mkyong.core;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Customer {
String name;
int age;
int id;
public String getName() {
return name;
}
@XmlElement
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
@XmlElement
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
@XmlAttribute
public void setId(int id) {
this.id = id;
}
}
package com.mkyong.core;
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
public class JAXBExample {
public static void main(String[] args) {
Customer customer = new Customer();
customer.setId(100);
customer.setName("mkyong");
customer.setAge(29);
try {
File file = new File("C:\\file.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(customer, file);
jaxbMarshaller.marshal(customer, System.out);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
的答案只包括DOM/SAX和复制一个JAXB实例的粘贴实现。
但是,当您使用XML时,一个大的领域就是缺失。在许多项目/程序中,需要存储/检索一些基本的数据结构。你的程序已经有了一个适合你的漂亮而闪亮的业务对象/数据结构的类,你只需要一个舒适的方式将这些数据转换为XML结构,这样你就可以做更多的魔术(存储,加载,发送和使用XSLT) 。
这是XStream的光芒。您只需注解持有数据的类,或者如果您不想更改这些类,则可以配置用于编组(对象 - > xml)或解组(xml - >对象)的XStream实例。
内部XStream使用反射,标准Java对象序列化的readObject和readResolve方法。
你得到一个很好的和快速的教程here:
要给它是如何工作的一个简短概述,我还提供了Marshalls和一个解组数据结构的一些示例代码。 编组/解组发生在main
方法中,其余的只是生成一些测试对象并向它们填充一些数据的代码。 配置xStream
实例非常简单,编组/解组每一行都有一行代码。
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import com.thoughtworks.xstream.XStream;
public class XStreamIsGreat {
public static void main(String[] args) {
XStream xStream = new XStream();
xStream.alias("good", Good.class);
xStream.alias("pRoDuCeR", Producer.class);
xStream.alias("customer", Customer.class);
Producer a = new Producer("Apple");
Producer s = new Producer("Samsung");
Customer c = new Customer("Someone").add(new Good("S4", 10, new BigDecimal(600), s))
.add(new Good("S4 mini", 5, new BigDecimal(450), s)).add(new Good("I5S", 3, new BigDecimal(875), a));
String xml = xStream.toXML(c); // objects -> xml
System.out.println("Marshalled:\n" + xml);
Customer unmarshalledCustomer = (Customer)xStream.fromXML(xml); // xml -> objects
}
static class Good {
Producer producer;
String name;
int quantity;
BigDecimal price;
Good(String name, int quantity, BigDecimal price, Producer p) {
this.producer = p;
this.name = name;
this.quantity = quantity;
this.price = price;
}
}
static class Producer {
String name;
public Producer(String name) {
this.name = name;
}
}
static class Customer {
String name;
public Customer(String name) {
this.name = name;
}
List<Good> stock = new ArrayList<Good>();
Customer add(Good g) {
stock.add(g);
return this;
}
}
}
好了,已经有DOM,JAXB及XStream在答案的列表,还有读写XML完全不同的方式:Data projection您可以通过使用库分离的XML结构和Java结构它为XML数据提供了可读写视图作为Java接口。从tutorials:
鉴于一些真实世界的XML:
<weatherdata>
<weather
...
degreetype="F"
lat="50.5520210266113" lon="6.24060010910034"
searchlocation="Monschau, Stadt Aachen, NW, Germany"
... >
<current ... skytext="Clear" temperature="46"/>
</weather>
</weatherdata>
随着数据投影,你可以定义投影接口:
public interface WeatherData {
@XBRead("/weatherdata/weather/@searchlocation")
String getLocation();
@XBRead("/weatherdata/weather/current/@temperature")
int getTemperature();
@XBRead("/weatherdata/weather/@degreetype")
String getDegreeType();
@XBRead("/weatherdata/weather/current/@skytext")
String getSkytext();
/**
* This would be our "sub projection". A structure grouping two attribute
* values in one object.
*/
interface Coordinates {
@XBRead("@lon")
double getLongitude();
@XBRead("@lat")
double getLatitude();
}
@XBRead("/weatherdata/weather")
Coordinates getCoordinates();
}
,并使用此接口的实例一样的POJO:
private void printWeatherData(String location) throws IOException {
final String BaseURL = "http://weather.service.msn.com/find.aspx?outputview=search&weasearchstr=";
// We let the projector fetch the data for us
WeatherData weatherData = new XBProjector().io().url(BaseURL + location).read(WeatherData.class);
// Print some values
System.out.println("The weather in " + weatherData.getLocation() + ":");
System.out.println(weatherData.getSkytext());
System.out.println("Temperature: " + weatherData.getTemperature() + "°"
+ weatherData.getDegreeType());
// Access our sub projection
Coordinates coordinates = weatherData.getCoordinates();
System.out.println("The place is located at " + coordinates.getLatitude() + ","
+ coordinates.getLongitude());
}
这部作品甚至创建XML时,XPath表达式可以WRI表。
SAX解析器与DOM解析器的工作方式不同,既不会将任何XML文档加载到内存中,也不会创建任何XML文档的对象表示形式。相反,SAX解析器使用回调函数(org.xml.sax.helpers.DefaultHandler)来通知客户端XML文档结构。
SAX解析器比DOM解析器速度更快,占用的内存也更少。 请参阅以下SAX回调方法:
startDocument()and endDocument() - 在XML文档的开始和结束处调用的方法。 startElement()和endElement() - 在文档元素的开始和结束处调用的方法。 characters() - 使用XML文档元素的开始标记和结束标记之间的文本内容调用的方法。 1. XML文件 创建一个简单的XML文件。
<?xml version="1.0"?>
<company>
<staff>
<firstname>yong</firstname>
<lastname>mook kim</lastname>
<nickname>mkyong</nickname>
<salary>100000</salary>
</staff>
<staff>
<firstname>low</firstname>
<lastname>yin fong</lastname>
<nickname>fong fong</nickname>
<salary>200000</salary>
</staff>
</company>
- 爪哇文件 使用SAX解析器来解析XML文件。
进口javax.xml.parsers中。SAXParser的;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class ReadXMLFile {
public static void main(String argv[]) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
DefaultHandler handler = new DefaultHandler() {
boolean bfname = false;
boolean blname = false;
boolean bnname = false;
boolean bsalary = false;
public void startElement(String uri, String localName,String qName,
Attributes attributes) throws SAXException {
System.out.println("Start Element :" + qName);
if (qName.equalsIgnoreCase("FIRSTNAME")) {
bfname = true;
}
if (qName.equalsIgnoreCase("LASTNAME")) {
blname = true;
}
if (qName.equalsIgnoreCase("NICKNAME")) {
bnname = true;
}
if (qName.equalsIgnoreCase("SALARY")) {
bsalary = true;
}
}
public void endElement(String uri, String localName,
String qName) throws SAXException {
System.out.println("End Element :" + qName);
}
public void characters(char ch[], int start, int length) throws SAXException {
if (bfname) {
System.out.println("First Name : " + new String(ch, start, length));
bfname = false;
}
if (blname) {
System.out.println("Last Name : " + new String(ch, start, length));
blname = false;
}
if (bnname) {
System.out.println("Nick Name : " + new String(ch, start, length));
bnname = false;
}
if (bsalary) {
System.out.println("Salary : " + new String(ch, start, length));
bsalary = false;
}
}
};
saxParser.parse("c:\\file.xml", handler);
} catch (Exception e) {
e.printStackTrace();
}
}
}
结果
开始元素:公司
开始元素:员工
开始元素:名字
名字:勇
结束元素:名字
开始元素:名字
姓:mook kim
结束语元:姓氏
开始元素:昵称
昵称:mkyong
结束元素:昵称
等等...
源(MyKong) - http://www.mkyong.com/java/how-to-read-xml-file-in-java-sax-parser/
- 1. 如何读取/写入xml文件?
- 2. 读取和写入XML文件
- 3. 如何读取和写入文件
- 4. 如何读取和写入文件
- 5. 如何从Perl读取和写入XML?
- 6. 读取和写入文件
- 7. 写入和读取文件
- 8. 读取正在写入的XML文件
- 9. Python文件读取二进制文件和写入xml
- 10. 用Slick2D编写和读取XML文件
- 11. 在写入XML文件时读取XML文件PHP
- 12. 如何读取和写入XML文档节点值?
- 13. 读取和写入文本文件
- 14. 如何使用vb.net读取/写入远程xml文件?
- 15. 如何读取XML文件并写入List <>?
- 16. 如何读取/写入ASCII .pgm文件
- 17. 如何读取,写入gwan的文件
- 18. 如何读取和解析.xml文件
- 19. 使用XSLT读取和写入XML文件
- 20. 使用“!”读取和写入XML文件性格
- 21. 使用PHP读取和写入XML文件
- 22. 读取和写入,并从XML文件在Android
- 23. 如何读取XML文件
- 24. 在Haskell中读取和写入文件
- 25. Python快速读取和写入文件
- 26. 从csv文件读取和写入
- 27. 麻烦读取和写入文件c#
- 28. 同时写入和读取文件
- 29. 读取和写入JSON文件Java
- 30. phonegap读取和写入json文件
是工作需要这个DTD文件,或者我们可以读取没有dtd的xml?如果需要dtd,我们可以轻松地从xml生成一个dtd,而不是自己输入它。 – 2014-10-29 21:38:18
你可以离开dtd文件。确保您还从xml文件中消除对它的引用:<!DOCTYPE roles SYSTEM“roles.dtd”>。您可以找到免费的dtd生成器应用程序或使用在线服务。他们生成一个“足够好”的dtd文件来开始。通常你将不得不修改它一点。 –
感谢您的回复。 :) – 2014-10-30 13:43:47