2012-04-29 10:14
出差时间有点不规律,本想早点写的。
先说dom4j,其实我也是个初学者,对于这个东西也不是很了解,只知道这个解析的效率最高。
代码可以参考IBM的文档个人觉得非常好。
- public class XmlDom4J {
- /**
- * 生成xml文件
- * @since 生成xml 具有一定的缩进格式
- */
- public void generateDocument() {
- //使用 DocumentHelper 类创建一个文档实例。 DocumentHelper 是生成 XML 文档节点的 dom4j API 工厂类
- Document document = DocumentHelper.createDocument();
- //使用 addElement() 方法创建根元素 catalog 。 addElement() 用于向 XML 文档中增加元素
- Element catalogElement = document.addElement("catalog");
- //在 catalog 元素中使用 addComment() 方法添加注释“An XML catalog”。
- catalogElement.addComment("An XML Catalog");
- //在 catalog 元素中使用 addProcessingInstruction() 方法增加一个处理指令。
- catalogElement.addProcessingInstruction("target", "text"); //还没弄清楚什么意思
- //在 catalog 元素中使用 addElement() 方法增加 journal 元素
- Element journalElement = catalogElement.addElement("journal");
- //使用 addAttribute() 方法向 journal 元素添加 title 和 publisher 属性。
- journalElement.addAttribute("title", "XML Zone");
- //向 article 元素中添加 journal 元素。
- journalElement.addAttribute("publisher", "IBM developerWorks");
- Element articleElement = journalElement.addElement("article");
- //为 article 元素增加 level 和 date 属性。
- articleElement.addAttribute("level", "Intermediate");
- articleElement.addAttribute("date", "December-2001");
- //向article中添加title元素
- Element titleElement = articleElement.addElement("title");
- //使用 setText() 方法设置 article 元素的文本。
- titleElement.setText("Java configuration with XML Schema");
- //使用 setText() 方法设置 article 元素的文本。
- Element authorElement = articleElement.addElement("author");
- //在 article 元素中增加 author 元素.
- Element firstNameElement = authorElement.addElement("firstname");
- //在 author 元素中增加 firstname 元素并设置该元素的文本。
- firstNameElement.setText("Marcello");
- //在 author 元素中增加 lastname 元素并设置该元素的文本。
- Element lastNameElement = authorElement.addElement("lastname");
- lastNameElement.setText("Vitaletti");
- /* 因为没有DTD文件,所以如果使用了,却没有文件,将解析出错 */
- //可以使用 addDocType() 方法添加文档类型说明
- // document.addDocType("catalog", null, "file://c:/Dtds/catalog.dtd");
- try {
- // String filePath = "D:\\catalog\\";
- // String fileName = "catalog.xml";
- // File file = estimateFile(filePath,fileName);
- OutputFormat format = new OutputFormat(" ",true); //控制输出的格式 indent:缩进, true: 开启
- format.setEncoding("gb2312");
- XMLWriter output = new XMLWriter(new FileWriter(new File("d:/catalog.xml")),format);
- output.write(document);
- output.close();
- } catch (IOException e) {
- System.out.println(e.getMessage());
- }
- }
我仿照文档写的基本没什么改动,解析的话用dom4j只要得到document就一步一步循环出来就可以了
- SAXReader saxReader = new SAXReader();
- Document document = saxReader.read(inputXml);
有的xml简单 有的xml复杂 复杂的话就需要考虑循环嵌套层数了想在ibm文档中使用的
- List list = document.selectNodes("//article/@level" );
这种能够直接读取节点的方法需要一个额外的jaxen.jar包,才能有XPath支持。
接下来说下jibx解析xml,用jibx解析好在它不只是为你解析,它可以做的更多。但你要想使用它也需要做的更多一点----绑定。
Customer对象
- public class Customer {
- public Person person;
- public String street;
- public String city;
- public String state;
- public Integer zip;
- public String phone;
-
-
- }
Person对象
- public class Person {
- public int customerNumber;
- public String firstName;
- public String lastName;
-
-
- }
data.xml文件
- <?xml version="1.0" encoding="UTF-8"?>
- <customer>
- <person>
- <cust-name>123456789 </cust-name>
- <first-name>jhone</first-name>
- <last-name>smith</last-name>
- </person>
- <street>12345 happy lane</street>
- <city>plunk</city>
- <state>WA</state>
- <zip>98059</zip>
- <phone>888.555.1234</phone>
- </customer>
binding.xml文件
- <?xml version="1.0" encoding="UTF-8"?>
- <binding name="binding" package="org.daemonbelief.mythink.xmlhandle.xmlbean">
- <mapping name="customer" class="org.daemonbelief.mythink.xmlhandle.xmlbean.Customer">
- <structure name="person" field="person" type="org.daemonbelief.mythink.xmlhandle.xmlbean.Person">
- <value name="cust-name" field="customerNumber"/>
- <value name="first-name" field="firstName"/>
- <value name="last-name" field="lastName"/>
- <!-- value style="text" field="lastName"/-->
- </structure>
- <value name="street" field="street"/>
- <value name="city" field="city"/>
- <value name="state" field="state"/>
- <value name="zip" field="zip"/>
- <value name="phone" field="phone"/>
- </mapping>
- </binding>
build_binding.xml文件
- <?xml version="1.0"?>
- <project basedir="." default="bind">
-
- <!-- The following block is intended to set the jibx-home location. It first
- checks the relative location of the JiBX libraries when this starter example
- is run directly from the JiBX distribution, then (if that fails), looks for
- an environmental variable JIBX_HOME with the installation path. If you prefer
- to just set the path directly in this file, uncomment the following line and
- set the value to the appropriate directory, then delete the rest of the Ant
- commands down to the end of this block. -->
- <!-- <property name="jibx-home" value="jibx-home-directory-path"/> -->
- <property file="build.properties"/>
- <!--property name="jibx-home" value="${sourcedir}"/-->
- <available file="${jibxhome}/lib/jibx-bind.jar" property="jibx-home" value="${sourcedir}"/>
- <property environment="env"/>
- <condition property="jibx-home" value="${sourcedir}">
- <and>
- <not>
- <isset property="jibx-home"/>
- </not>
- <available file="${jibxhome}/lib"/>
- </and>
- </condition>
- <!-- End of jibx-home location setting block. -->
-
- <!-- make sure required jars are present -->
- <condition property="runtime-jars-found">
- <available file="${jibxhome}/lib/jibx-run.jar"/>
- </condition>
- <condition property="binding-jars-found">
- <and>
- <available file="${jibxhome}/lib/bcel.jar"/>
- <available file="${jibxhome}/lib/jibx-bind.jar"/>
- <available file="${jibxhome}/lib/jibx-run.jar"/>
- </and>
- </condition>
-
- <!-- set classpath for compiling and running application with JiBX -->
- <path id="classpath">
- <fileset dir="${jibxhome}/lib" includes="*.jar"/>
- <pathelement location="${jibxhome}/classes"/>
- </path>
-
- <!-- make sure runtime jars are present -->
- <target name="check-runtime">
- <fail unless="jibx-home">JiBX home directory not found - define JIBX_HOME system property or set path directly in build.xml file.</fail>
- <fail unless="runtime-jars-found">Required JiBX runtime jar jibx-run.jar was not found in JiBX home lib directory (${jibx-home}/lib)</fail>
- </target>
-
- <!-- make sure binding jars are present -->
- <target name="check-binding" depends="check-runtime">
- <fail unless="binding-jars-found">Required JiBX binding jar jibx-bind.jar or bcel.jar was not found in JiBX home lib directory (${jibx-home}/lib)</fail>
- </target>
-
- <!-- run the binding compiler -->
- <target name="bind" depends="check-binding">
-
- <echo message="Running JiBX binding compiler"/>
- <taskdef name="bind" classname="org.jibx.binding.ant.CompileTask">
- <classpath>
- <fileset dir="${jibxhome}/lib" includes="*.jar"/>
- </classpath>
- </taskdef>
- <bind binding="${sourcedir}/WebContent/filefolder/binding.xml">
- <classpath refid="classpath"/>
- </bind>
-
- </target>
- </project>
build.properties文件
- jibxhome=D:\\ProgramFiles\\workspace\\SHXY_YDJX_JIBX\\WebContent\\WEB-INF
- sourcedir=D:\\ProgramFiles\\workspace\\SHXY_YDJX_JIBX
首先要先写好Java对象和数据xml文件,然后用binding来绑定对象。绑定写好后就需要用ant运行build_binding.xml来生成两个bind的class,可以用Navigater视图看到。bind好后,下面的工作就简单了
- public class Par***mlByJibx {
- public static Object parseSourceXml(Class clazz,String filename){
- IBindingFactory bindingfactory = null;
- Customer customer = new Customer();
- try {
- bindingfactory = BindingDirectory.getFactory(clazz);/* 绑定工厂 */
- IUnmarshallingContext unmarshallingcontext = bindingfactory.createUnmarshallingContext();/* 创建反编列的上下文 */
- FileInputStream fis = new FileInputStream(new File(filename));/* 文件输入流 获取文件信息 */
- customer = (Customer)unmarshallingcontext.unmarshalDocument(fis, null);/* 将'流'中的数据反编列得到相应的'对象' */
- IMarshallingContext marshallingcontext = bindingfactory.createMarshallingContext();/* 创建编列的上下文 */
- marshallingcontext.setIndent(2);/* 设置缩进 */
- FileOutputStream fos = new FileOutputStream("parsetest.xml");/* 文件输出流 输出对象信息 */
- marshallingcontext.marshalDocument(customer, "UTF-8",null,fos);/* 以指定编码编列'对象'到文件 */
-
- } catch (JiBXException e) {
- e.printStackTrace();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- return customer;
-
- }
- }
用jibx解析出来的就会直接将属性转换给对象。使用方便 绑定复杂。
jibx需要的jar包:ant-contrib.jar
ant.jar
antlr.jar
bcel.jar
jibx-bind.jar
jibx-extras.jar
jibx-run.jar
log4j-1.2.12.jar
xpp3.jar
因为bind比较复杂,弄了好久才绑定好。可以参考下官方文档
总结:对于如何解析复杂xml我不是很清楚,但这两种方式是比较实用,并且常用的。看情况和复杂程度来决定使用什么。没有最好的,只有更适合的。
阅读(3181) | 评论(0) | 转发(0) |