自定义解析xml案例,其原理见:NameSpaceHandler
public class People {
private String name;
private String gender;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
我们希望自定义一个名称空间"pp",我们自定义解析其people标签,加载这个People 这个 bean。
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:pp="http://www.springframework.org/schema/pp"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/pp
http://www.springframework.org/schema/beans/spring-pp-3.1.xsd
">
<!--
<bean class="com.jack.ascp.purchase.app.test.spring.parse.xml.People" pp:property = "name:jpl,gender:man">
</bean>
-->
<pp:people>
<pp:property>name:jpl,gender:man</pp:property>
</pp:people>
</beans>
定义其名称空间为"http://www.springframework.org/schema/pp",对应schema文件http://www.springframework.org/schema/beans/spring-pp-3.1.xsd,由于这个文件是我们自定义的,网络上并没有,因此我们为其建一个本地文件:custom-spring-pp.xsd
custom-spring-pp.xsd:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://www.springframework.org/schema/pp"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.springframework.org/schema/pp">
<xsd:attribute name="property" type="xsd:string"/>
<xsd:element name="property" type="xsd:string"/>
<!-- 定义一个element叫people -->
<xsd:element name="people">
<!-- 它是一个复杂类型 -->
<xsd:complexType>
<!-- 它里面包含一个序列 -->
<xsd:sequence>
<!-- 有一个property属性作为孩子成员 -->
<xsd:element ref="property"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
在spring.schemas文件中配置custom-spring-pp.xsd为本地schema文件。
http\://www.springframework.org/schema/beans/spring-pp-3.1.xsd=custom-spring-pp.xsd
然后为这个名称空间配置它的NamespaceHandler
public class PPNameSpaceHandler implements NamespaceHandler {
private final static String PROPERTY = "property";
private final static String PEOPLE = "people";
@Override
public void init() {
}
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
if (PEOPLE.equals(element.getLocalName())) {
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClassName(People.class.getName());
String beanName = parserContext.getReaderContext().generateBeanName(beanDefinition);
NodeList childNodes = element.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node node = childNodes.item(i);
if (PROPERTY.equals(node.getLocalName())) {
String value = node.getFirstChild().getNodeValue().trim();
String[] pairs = StringUtils.tokenizeToStringArray(value, ",");
for (String pair : pairs) {
String[] attrs = StringUtils.tokenizeToStringArray(pair, ":");
PropertyValue pv = new PropertyValue(attrs[0], attrs[1]);
beanDefinition.getPropertyValues().addPropertyValue(pv);
}
}
}
parserContext.getRegistry().registerBeanDefinition(beanName, beanDefinition);
}
return null;
}
@Override
public BeanDefinitionHolder decorate(Node source, BeanDefinitionHolder definition, ParserContext parserContext) {
if (PROPERTY.equals(source.getLocalName())) {
String value = source.getNodeValue().trim();
String[] pairs = StringUtils.tokenizeToStringArray(value, ",");
for (String pair : pairs) {
String[] attrs = StringUtils.tokenizeToStringArray(pair, ":");
PropertyValue pv = new PropertyValue(attrs[0], attrs[1]);
definition.getBeanDefinition().getPropertyValues().addPropertyValue(pv);
}
}
return definition;
}
}
接着是我们的测试类:
public class PPNameSpaceHandlerDebug {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("custom_xml_parse_demo.xml");
People people = context.getBean(People.class);
System.out.println(people.getGender());
System.out.println(people.getName());
}
}