将XML结构解析为一组简单的通用映射和列表

时间:2010-09-08 15:11:35

标签: java xml-parsing

How to convert XML to java.util.Map and vice versa有点相关,只是更通用。

我有一个XML文档,我想将它转换为一组非常通用的键/值对(在Java中)。基本思想是我们可以解析几乎每个XML文档并将其直接传递给JSP文件,该文件可以读取值并显示它们。

假设一个XML结构如下:

<root>
  <items>
   <item id="10">Some item here</item>
  </items>
  <things>
   <thing awesome="true">
    <orly-owl hoot="woot" />
   </thing>
  </things>
</root>

输出将是一组包含值,列表和其他地图的Map对象。理想情况下,它是如何在(伪)JSP文件中读取的:

<c:forEach var="item" items="${root.items}">
  ${item.id}
  ${item.text}
</c:forEach>
<c:forEach var="things" items="${root.things}">
  Is it awesome? ${thing.awesome}
  orly? ${thing.orly-owl.hoot}
</c:forEach>

基本上,它是一个包含一组简单规则的xml解析器。

对于每个XML实体:

是否有子节点?

  

将地图添加到地图中,其中节点名称为键,List(地图)为值    它有属性或价值吗?   添加带有属性名称作为键的映射条目,将属性值作为值

添加

......或某种程度的东西。我还没有正确考虑数据结构。

所以我的问题是:是否有现成的解析器可以执行此操作或类似的操作?

我今天发现并尝试过的所有内容都映射到固定的对象层次结构,即您必须使用具有自己属性的Item对象列表创建根对象。这对于s​​é来说也不错(它可以基于(待编写/设计)DTD对象自动生成,但是我目前的任务是试用这两个选项。试过第一个,它会在那些映射后起作用xml文件对我来说很有意义,错误消息开始告诉我我做错了什么,但是却无法弄清楚如何做第二个(读取:写一个递归递归的递归xml解析器(dom或sax))

在这个问题中可能缺少一致性,这是五点钟。


编辑,经过深思熟虑之后。它将起作用(即,将对象发送到可以包含值,映射和列表的JSP),但是在解析时会出现非常大的问题,例如在下一个示例中:

<root thing="thine mother">
  <thing mabob="yus" />
  <thing mabob="nay" />
  <items>
    <item id=1" />
  </items>
</root>

在这个特定的例子中,根下有两个同名的thing-elements。同名的元素应该进入List。但是,在同一级别有一个items元素,它是一个单独的元素,应该作为一个map项目。除此之外,根元素中还有第三个名为'element'的东西,整个事情都被误解了。

如果不预先分析结构(并设置一个标志,例如'在这个特定元素下有同名和唯一命名的元素'),你就不能假设这一点。我要做的最后一件事是强制XML根据特定的结构。

我的同事实际上建议通过XSL运行XML,以便它'更平坦'(更像数据库行),或者让xml输出的最大深度为1。不是一种选择,真的。

反正。感谢所有的建议,似乎这不是一个非常合理的解决方案 - 至少在没有搞砸XML和常识的基本规则和惯例的情况下。

接下来的想法 - 让JSP直接使用XML JSTL库呈现Document。

4 个答案:

答案 0 :(得分:3)

JDOM当然可以为您提供从元素构建的列表。该库已存在很长时间,并且非常易于使用。 http://jdom.org/

答案 1 :(得分:2)

似乎JSTL XML bindings会完全符合您的要求。

并且您不太可能使用列表和地图找到完全符合您要求的任何内容的原因是因为XML不能整齐地转换为列表和地图(主要是因为“您如何处理属性与内容不同? “)。

答案 2 :(得分:1)

Java Architecture for XML Binding (JAXB)应该在你的候选名单上。这是一个简短的tutorial introduction

答案 3 :(得分:1)

apache-commons Digester可以执行此操作,它是SAX解析器的包装器,允许您创建将数据解组到对象中的规则。

OTOH如果您想知道如何进行递归解析,可以查看this article一个有趣的方法(使用递归转换网络)。我们的想法是创建一个对象网络,显示xml元素之间的关系,并在使用堆栈进行解析时跟踪您在此网络中的位置。