JAVA解析XML(StAX)

本文介绍了JAVA中使用StAX解析XML的方法,通过示例展示如何将XML文档转化为一系列事件,包括主要和次要事件的解析过程。

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

<?xml version="1.0"?>

<!-- xxxtask, not xxxChecker -->

<service>
	<item>
		<task>HostAliveTask</task>
		<strategy>repeat</strategy>
		<repeatFreq>180</repeatFreq>
	</item>
	<item>
		<task>WebpageRespTask</task>
		<strategy>repeat</strategy>
		<repeatFreq>180</repeatFreq>
	</item>
	
	<item>
		<task>AlarmNumTask</task>
		<strategy>daily</strategy>
		<dailyRuntime>16:45:00</dailyRuntime>
	</item>
</service>


import global.Global;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Calendar;
import java.util.Date;
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

import org.apache.log4j.Logger;

/**
 * schedule the checking task.
 */
public class Scheduler {
//	private static final String TAG_SERVICE = "service";
	private static final String TAG_ITEM = "item";
	private static final String TAG_TASK = "task";
	
	private static final String TAG_STRATEGY = "strategy";
	private static final String STRATEGE_REPEAT = "repeat";
	private static final String STRATEGE_DAILY = "daily";
	
	private static final String TAG_REPEATFREQ = "repeatFreq";
	private static final String TAG_DAILYRUNTIME = "dailyRuntime";
	
	private static Logger _logger = Logger.getLogger(Scheduler.class);
	
	void readConfig(){
		try {
			// First create a new XMLInputFactory
			XMLInputFactory inputFactory = XMLInputFactory.newInstance();
			inputFactory.setProperty("javax.xml.stream.isCoalescing", true); //否则读取多行数据时出问题

			// Setup a new eventReader
			InputStream in = new FileInputStream(Global.SERVICE_CONFIGURE_FILE);
			XMLEventReader eventReader = inputFactory.createXMLEventReader(in);

			// One specification
			String task 	= null;
			String strategy = null;
			Integer freq 	= null;// by second
			
			// for daily job
			Date firstTime 	= null;
			Calendar calendar = Calendar.getInstance();  
	        
			// Read the XML document
			while (eventReader.hasNext()) {
				XMLEvent event = eventReader.nextEvent();

				if (event.isStartElement()) {
					StartElement startElement = event.asStartElement();

					if (startElement.getName().getLocalPart().equals(TAG_ITEM)) {
					/*
						Iterator<Attribute> attributes = startElement.getAttributes();
						while (attributes.hasNext()) {
							attributes.next();
							// skip
						}
					*/
					}

					if (event.asStartElement().getName().getLocalPart().equals(TAG_TASK)) {
						event = eventReader.nextEvent();
						task = event.asCharacters().getData();
						
						continue;
					}
					if (event.asStartElement().getName().getLocalPart().equals(TAG_STRATEGY)) {
						event = eventReader.nextEvent();
						strategy = event.asCharacters().getData();
						
						continue;
					}
					
					if (event.asStartElement().getName().getLocalPart().equals(TAG_REPEATFREQ)) {
						event = eventReader.nextEvent();
						freq = Integer.parseInt(event.asCharacters().getData());
						
						continue;
					}
					
					if (event.asStartElement().getName().getLocalPart().equals(TAG_DAILYRUNTIME)) {
						event = eventReader.nextEvent();
						
						// hour:min:sec
						Scanner scanner = new Scanner(event.asCharacters().getData());
						scanner.useDelimiter(":");
						
						int hour = scanner.nextInt();
						int minute = scanner.nextInt();
						int second = scanner.nextInt();
						
						// firstTime (today)
						calendar.set(Calendar.HOUR_OF_DAY, hour);  
				        calendar.set(Calendar.MINUTE, minute);  
				        calendar.set(Calendar.SECOND, second);  
				        firstTime = calendar.getTime();
					
						continue;
					}
				}
				// If we reach the end of an item element we add it to the list
				if (event.isEndElement()) {
					EndElement endElement = event.asEndElement();
					if (endElement.getName().getLocalPart().equals(TAG_ITEM)) {
						
						Timer timer = new Timer();

						if(strategy.equals(STRATEGE_REPEAT)) {
							
							Class<?> clz = Class.forName(Global.TASK_PACKAGE_PREFIX + task);
							TimerTask ctr = (TimerTask)clz.newInstance();
							
							timer.schedule(ctr, 0, freq*1000);
							
						} else if(strategy.equals(STRATEGE_DAILY)){
							
							Class<?> clz = Class.forName(Global.TASK_PACKAGE_PREFIX + task);
							TimerTask ctr = (TimerTask)clz.newInstance();
							
							timer.schedule(ctr, firstTime, Global.PERIOD_DAY);
						} else {
							_logger.error("Unexpected configuration option "+ strategy +" in " + Global.SERVICE_CONFIGURE_FILE);
						}
					}
				}
			}
		} catch (FileNotFoundException ex) {
			_logger.error(ex.getLocalizedMessage(), ex);
			
		} catch (XMLStreamException ex) {
			_logger.error(ex.getLocalizedMessage(), ex);
			
		} catch (Exception ex) {
			_logger.error(ex.getLocalizedMessage(), ex);
			
		}
	}

}


//===================================================================================================================================

Stax介绍参考:Sample Event Mapping


Event TypeDescription
StartDocumentReports the beginning of a set of XML events, including encoding, XML version, and standalone properties.
StartElementReports the start of an element, including any attributes and namespace declarations; also provides access to the prefix, namespace URI, and local name of the start tag.
EndElementReports the end tag of an element. Namespaces that have gone out of scope can be recalled here if they have been explicitly set on their corresponding StartElement.
CharactersCorresponds to XML CData sections and CharacterData entities. Note that ignorable whitespace and significant whitespace are also reported as Character events.
EntityReferenceCharacter entities can be reported as discrete events, which an application developer can then choose to resolve or pass through unresolved. By default, entities are resolved. Alternatively, if you do not want to report the entity as an event, replacement text can be substituted and reported as Characters.
ProcessingInstructionReports the target and data for an underlying processing instruction.
CommentReturns the text of a comment
EndDocumentReports the end of a set of XML events.
DTDReports as java.lang.String information about the DTD, if any, associated with the stream, and provides a method for returning custom objects found in the DTD.
AttributeAttributes are generally reported as part of a StartElement event. However, there are times when it is desirable to return an attribute as a standalone Attribute event; for example, when a namespace is returned as the result of an XQuery or XPath expression.
NamespaceAs with attributes, namespaces are usually reported as part of a StartElement, but there are times when it is desirable to report a namespace as a discrete Namespace event.

As an example of how the event iterator API maps an XML stream, consider the following XML document:

<?xml version="1.0"?>
<BookCatalogue xmlns="http://www.publishing.org">
  <Book>
    <Title>Yogasana Vijnana: the Science of Yoga</Title>
    <ISBN>81-40-34319-4</ISBN>
    <Cost currency="INR">11.50</Cost>
  </Book>
</BookCatalogue>

This document would be parsed into eighteen primary and secondary events, as shown below. Note that secondary events, shown in curly braces ({}), are typically accessed from a primary event rather than directly.

#Element/AttributeEvent
1version="1.0"StartDocument
2isCData = falseCharacters
data = "\n"
IsWhiteSpace = true
3qname = BookCatalogue:http://www.publishing.orgStartElement
attributes = null
namespaces = {BookCatalogue" -> http://www.publishing.org"}
4qname = BookStartElement
attributes = null
namespaces = null
5qname = TitleStartElement
attributes = null
namespaces = null
6isCData = falseCharacters
data = "Yogasana Vijnana: the Science of Yoga\n\t"
IsWhiteSpace = false
7qname = TitleEndElement
namespaces = null
8qname = ISBNStartElement
attributes = null
namespaces = null
9isCData = falseCharacters
data = "81-40-34319-4\n\t"
IsWhiteSpace = false
10qname = ISBNEndElement
namespaces = null
11qname = CostStartElement
attributes = {"currency" -> INR}
namespaces = null
12isCData = falseCharacters
data = "11.50\n\t"
IsWhiteSpace = false
13qname = CostEndElement
namespaces = null
14isCData = falseCharacters
data = "\n"
IsWhiteSpace = true
15qname = BookEndElement
namespaces = null
16isCData = falseCharacters
data = "\n"
IsWhiteSpace = true
17qname = BookCatalogue:http://www.publishing.orgEndElement
namespaces = {BookCatalogue" -> http://www.publishing.org"}
18EndDocument

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值