这里使用dom4j包来解析xml文件。
这里写了一个很简单的xml文件解析器。
xml格式需要按照下面的来写:
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="userBean" class="com.ice.ioc.document.UserBean">
<property name="username">
<value>张三</value>
</property>
<property name="password">
<value>123456</value>
</property>
</bean>
</beans>
必须要以这样的键值对的形式来表示,并且其中的属性需要和下面的代码一致。其中代码需要使用属性id,class。可以添加不同< bean>,但一定需要有id,有class.这样解析器才能解析出数据。< property>中有属性name,这个也是和下面代码一致。< value>可以不需要使用,但是需要在< property>值。
下面是就是一个简易的xml文件解析器。
public class Parse {
private Map<String, Object> beanMap = new HashMap<>();
/**
* 解析xml文件夹
* @param fileName
* @throws Exception
*/
public void init(String fileName) throws Exception {
File file = new File(fileName);
if (!file.exists() ) {
throw new Exception("文件名不正确");
}
SAXReader reader = new SAXReader();
Document document = reader.read(file);
Element root = document.getRootElement();
Element foo = null;
for (Iterator iterator = root.elementIterator(); iterator.hasNext();) {
foo = (Element) iterator.next();
Attribute id = foo.attribute("id");
Attribute cls = foo.attribute("class");
// 通过类名获取到类
Class bean = Class.forName(cls.getText());
BeanInfo beanInfo = Introspector.getBeanInfo(bean);
PropertyDescriptor[] pd = beanInfo.getPropertyDescriptors();
Method method = null;
Object object = bean.newInstance();
for (Iterator it = foo.elementIterator(); it.hasNext();) {
Element element = (Element) it.next();
Attribute name = element.attribute("name");
String value = null;
if (name.getValue() == null) {
for (Iterator keyIt = element.elementIterator(); keyIt.hasNext();) {
Element element2 = (Element) keyIt.next();
value = element2.getText();
break;
}
}else{
value = name.getValue();
}
for (int k = 0; k < pd.length; k++) {
if(pd[k].getName().equalsIgnoreCase(name.getText())){
method = pd[k].getWriteMethod();
method.invoke(object, value);
break;
}
}
}
beanMap.put(id.getText(), object);
}
}
public Object getObject(String key) {
return beanMap.get(key);
}
}
dom4jxml文件解析,获取SAXReader,并读取文件,获取Document,然后在获取Element跟元素。
SAXReader reader = new SAXReader();
Document document = reader.read(file);
Element root = document.getRootElement();
root元素相当于xml文件中< beans>,接下啦去遍历其中的子节点,并通过获取其中子节点中的属性。
for (Iterator iterator = root.elementIterator(); iterator.hasNext();) {
foo = (Element) iterator.next();
Attribute id = foo.attribute("id");//获取其中的id属性
Attribute cls = foo.attribute("class");//获取class属性
}
java中有一个来处理javabean缺省方式。内省(Introspector) 是Java 语言对 JavaBean 类属性、事件的一种缺省处理方法。通过它,来获取javabean,
Class bean = Class.forName(cls.getText());
BeanInfo beanInfo = Introspector.getBeanInfo(bean);
PropertyDescriptor[] pd = beanInfo.getPropertyDescriptors();
PropertyDescriptor类表示JavaBean类通过存储器导出一个属性。主要方法:
1. getPropertyType(),获得属性的Class对象;
2. getReadMethod(),获得用于读取属性值的方法;getWriteMethod(),获得用于写入属性值的方法;
3. hashCode(),获取对象的哈希值;
4. setReadMethod(Method readMethod),设置用于读取属性值的方法;
5. setWriteMethod(Method writeMethod),设置用于写入属性值的方法。
获取这< property>中的属性,接下就需要去判断< property>是否有值,还是有子节点。
Method method = null;
Object object = bean.newInstance();
//遍历< property>
for (Iterator it = foo.elementIterator(); it.hasNext();) {
Element element = (Element) it.next();
Attribute name = element.attribute("name");
String value = null;
//是否有值
if (name.getValue() == null) {
for (Iterator keyIt = element.elementIterator(); keyIt.hasNext();) {
Element element2 = (Element) keyIt.next();
value = element2.getText();
break;
}
}else{
value = name.getValue();
}
//从对象中匹配,并将值设置到对象中
for (int k = 0; k < pd.length; k++) {
if(pd[k].getName().equalsIgnoreCase(name.getText())){
method = pd[k].getWriteMethod();
method.invoke(object, value);
break;
}
}
}
上面的解析器已经做完,其中javabean对象:
public class UserBean {
private String userName;
private String password;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
这里的名称需要和xml文件中的属性名称一致。