2011-04-10 66 views
3

我目前正在学习Java以及如何处理XML数据。我一直在学习如何使用Java SAX来将我的xml数据解析为java对象。这个XML文档可以更改并添加额外的子项(例如:Birthday,height ...)。那么处理这个XML文档的最佳建议是什么?我被告知要使用对象是这样的:为每个XML子节点动态创建Java对象?

Object1.ID 
Object1.Emp_Id 
Object1.Emp_Name 
... 
Object2.ID 
Object2.Emp_Id 
Object2.Emp_Name 

如果XML接收到一个新的孩子,就像生日,那么应用程序将其添加到对象,例如:

Object1.ID 
Object1.Emp_Id 
Object1.Emp_Name 
Object1.Birthday 

有人能指出我正确的方向,我可以动态地创建像上面的例子那样的新对象,我可以将子节点放入?所以如果孩子节点改变了,我不必直接指定它呢?对不起,我不知道如果我解释这个权利。我正在学习SAX并找到了本教程,但似乎没有解释我想要做什么:Mapping XML to Java Objects

感谢yoU!

XML文件:

<?xml version = "1.0" ?> 
<Employee-Detail> 

<Employee> 
<ID no="1"> 
<Emp_Id> E-001 </Emp_Id> 
<Emp_Name> Vinod </Emp_Name> 
<Emp_E-mail> [email protected] </Emp_E-mail> 
<Sex>Male</Sex> 
<Age>25</Age> 
</ID> 
</Employee> 

<Employee> 
<ID no="2"> 
<Emp_Id> E-002 </Emp_Id> 
<Emp_Name> Amit </Emp_Name> 
<Emp_E-mail> [email protected] </Emp_E-mail> 
<Sex>Male</Sex> 
<Age>21</Age> 
</ID> 
</Employee> 
</Employee-Detail> 

回答

0

基本上有两种方法可以做到这一点。首先,您可以定义名称映射到XML元素的Java类。你可以手工完成,或者你可以使用像XmlBeans这样的工具(还有很多其他的工具)。两者都是相同的:你必须事先了解关于XML的一些东西。

另一种方法是不使用专用类,而是使用某种具有“名称”属性,属性映射和子级列表的通用“树节点”对象。文档对象模型(Document Object Model,DOM)是其标准版本,实际上,使用自动构建此树的DOM解析器是使用SAX的标准替代方案。您也可以创建自己的通用元素类,但您应该先使用DOM尝试它,以了解它如何适用于您的应用程序。

+1

这不是那种地方JAXB眼前一亮的东西? – 2011-04-10 02:40:37

+0

感谢您的输入,我会知道元素将如何配置,它只是我试图解决的子节点。子节点名称可以不同,因为它们将由用户创建,但所有父节点将相同以帮助应用程序导航文档。 – 2011-04-10 02:57:05

4

我个人非常喜欢使用JAXB。

您可以将该示例XML传递给XML模式(XSD)生成器。然后采用XSD并使用XJC工具生成Java对象。生成Java对象后,可以分别使用Marshaller和Unmarshaller类编组(保存/导出/写入)XML或解组(装载/导入/读取)它。

曾经有一个在线的XML到XSD转换器,在http://www.flame-ware.com/products/xml-2-xsd/,但它似乎在下降。不过,您可以免费下载Visual Studio的快速版本来完成相同的任务。

我喜欢这个教程JAXB:http://download.oracle.com/javaee/5/tutorial/doc/bnbah.html

我通常使用SAX解析只如果我想在为我解析多数民众赞成解析(几乎没有)的一切完全控制。

我不喜欢使用DOM方法,因为它需要先解析整个XML文档,然后才能真正对其进行解析,并且一旦解析完成,您需要做更多工作来配置解析器/ XML使用者知道这些领域实际上是做什么的。

至于你的动态孩子,我只是简单地在模式中包含代表键值对的无限数量的对象。由于为您生成的所有代码,它仍然可以节省您的时间。

XMLBeans的图书馆类似,JAXB,但我更喜欢后者,因为它被引导到Java的核心释放,同时XmlBeans的不是。

+0

问题:我可以像JAXB或SAX一样使用嵌套向量吗?我只是发现矢量可以被命名为任何东西,并可以为每个矢量对象保存任何东西。 (不知道我是否正确解释)。例如:创建一个矢量变量来保存一个xml元素父级名称。在该向量varialble中,我为该父项中的所有子项创建另一个向量。所以我可以实现Object1.child1,Object1.child2,Object1.child3 ...等等。 – 2011-04-10 05:41:45

+0

使用JAXB,您也可以从对象开始,这意味着模式不是必需的。还Java是一个标准(JSR-222),具有多个实现(新城,的EclipseLink MOXY,阿帕奇JaxMe),这就是为什么它被包含在Java SE 6.本标准的发展包括从XMLBeans的一个代表,以及其他对象-to-XML工具。 – 2011-04-10 10:55:04

+0

JAXB本地支持键值对的映射。所以是的,你可以嵌套=)。看看XMLAdapter。 另外,好的补充,Blaise! – 2011-04-11 07:37:24

1

另一种选择是XStream的:http://x-stream.github.io/。它不如JAXB灵活,但它的优点是不需要太多配置。

在你的情况你只需创建一个类:

public class Employee { 
    String Id; 
    String EmpId; 
    ... 
} 

XStream xstream = new XStream(); 
xstream.alias("Employee", Employee.class); 
xstream.useAttributeFor(Employee.class, "ID"); 
xstream.aliasField("no", Blog.class, "ID"); 
Employee e = (Employee)xstream.fromXML(xml); 

这是一个有点痛,不过,如果你的XML不干净映射到你的对象。

+0

但这种方法将意味着我将不得不仍然知道孩子标签在xml文件中,对吗?我希望能够根据文件中的子标签动态创建对象。 – 2011-04-10 04:00:38

+0

如果你映射到一个特定的XML格式没有在配置多大的区别:http://bdoughan.blogspot.com/2010/10/how-does-jaxb-compare-to-xstream.html – 2011-04-10 10:57:36

+0

我不不懂“动态创建”。只要子标签与现有的类/字段名称约定匹配,XStream就会为您实例化并映射。 – Dave 2011-04-13 03:14:42