【问题标题】:Non-problematic XML-to-Java binding没有问题的 XML 到 Java 绑定
【发布时间】:2012-06-06 21:56:53
【问题描述】:

我到处寻找将 XML 元素绑定到 Java 类的好方法。这听起来是一件相当容易实现的事情(对于一些简单的价值),但无论我在哪里看,都需要 XSD、显式映射和一堆其他真正阻碍我的东西。

这是代表站点地图的 Java 对象(可能不完整)的想法。

public class Sitemap {

    private List<Url> urls;

    public List<Url> getUrls() {
        return urls;
    }

    public void setUrls(List<Url> urls) {
        this.urls = urls;
    }
}

我正在寻找可以让我做的事情:

Sitemap sitemap = (Sitemap) Foo.fromXml("sitemap.xml")

类似的东西,或者至少类似的东西。有这样的吗?

【问题讨论】:

标签: java xml data-binding


【解决方案1】:

以下是如何使用 JAXB (JSR-222) 完成此操作。 Java SE 6 中包含一个实现。还有其他实现,例如 EclipseLink MOXy(我是技术主管)。

简短回答

您可以将以下 API 调用与带有任何注释或 XML 模式的 JAXB 一起使用。

Sitemap sitemap = JAXB.unmarshal(xml, Sitemap.class);

长答案

下面是一个更详细的例子。

站点地图

我稍微修改了你的课程。我不确定Url 类是什么,所以我将其更改为java.net.URL。请注意域模型上不需要注释。

package forum10854001;

import java.net.URL;
import java.util.List;

public class Sitemap {

    private List<URL> urls;

    public List<URL> getUrls() {
        return urls;
    }

    public void setUrls(List<URL> urls) {
        this.urls = urls;
    }
}

演示

我创建了一个JAXBContext,而不是简短答案中使用的代码。 JAXBContext 是一个线程安全的对象,表示所有已初始化的元数据。 MarshallerUnmarshaller 对象提供了比 JAXB 类更多的灵活性。

下面的代码演示了如何读取 XML 并将其写回:

package forum10854001;

import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Sitemap.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        StreamSource xml = new StreamSource("src/forum10854001/input.xml");
        JAXBElement<Sitemap> jaxbElement = unmarshaller.unmarshal(xml, Sitemap.class);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(jaxbElement, System.out);

    }

}

input.xml/Output

<?xml version="1.0" encoding="UTF-8"?>
<sitemap>
    <urls>http://www.eclipse.org/eclipselink/moxy.php</urls>
    <urls>http://jaxb.java.net</urls>
</sitemap>

更多信息

【讨论】:

  • +1 很好的答案!我得看看 MOXy,看起来我可能会觉得很有用。
  • Blaise - 我过去经常使用 XStream(请参阅我的回答),但我很高兴看到并了解类似 MOXy 的“更简单”方法。您认为 JSR-222/MOXy 相对于 XStream 的优势是什么?
  • @user949300 - JAXB 的优点包括:多种实现,Java SE 6 中包含的 impl,JAX-WS 和 JAX-RS Web 服务的绑定层,可以从 Java 类或 XML 模式开始(XStream FAQ为后者推荐 XMLBeans:xstream.codehaus.org/faq.html#Uses)。 MOXy 的其他优势;基于路径的映射 (blog.bdoughan.com/2010/07/xpath-based-mapping.html)、外部映射文档、对 JPA 实体的支持等。XStream 可以进行 JSON 绑定,但 MOXy 也可以:blog.bdoughan.com/2011/08/…
  • 所以,我玩了一下 JAXB。我想说 XStream 的一个轻微 优点是它仍然可以工作,非常简单,不会强迫您向对象的字段添加注释。使用 JAXB,您要么需要添加注释(从长远来看,这可能是一个好主意),要么需要通过内省器执行额外的步骤。对吗?
  • 按照我的例子,不需要注释。
【解决方案2】:

您也可以考虑XStream。下面是与 Blaise 的代码大致等效的代码,但为了多样化而朝着相反的方向工作(从 Object 开始,而不是 XML):

public class Sitemap{
      private List<URL> urls = new ArrayList();

      // I left out the setters and getters

      public static void main(String[] args) throws IOException {
         Sitemap sitemap = new Sitemap();
         sitemap.urls.add(new URL("http://www.eclipse.org/eclipselink/moxy.php"));
         sitemap.urls.add(new URL("http://jaxb.java.net"));

         XStream xs = new XStream(new DomDriver());
         String xmlString = xs.toXML(sitemap);
         System.out.println(xmlString);
         Sitemap readBack = (Sitemap) xs.fromXML(xmlString);
      }
   }

产生以下输出:

<com.your.name.here.Sitemap>
  <urls>
    <url>http://www.eclipse.org/eclipselink/moxy.php</url>
    <url>http://jaxb.java.net</url>
  </urls>
</com.your.name.here.Sitemap>

您可以在调试器中设置断点并查看 readBack,它具有两个 URL。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-24
    • 2011-08-16
    • 2011-08-16
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 2011-02-02
    相关资源
    最近更新 更多