2014-12-13 150 views
3

我想使用JAXB解析xml文件。 我的问题是,我需要跳过根节点,如果我从xml文件中删除它,我得到我所需要的,否则 - 我得到一个空的对象。忽略JAXB中的根元素

我给一个简单的XML和我的代码(它的工作方式):

XML:

<?xml version="1.0" encoding="utf-8"?> 
<Root> 
<!-- <Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:noNamespaceSchemaLocation="Office.xsd"> 
--> 
    <Office> 
     <Employees> 
      <Employee> 
       <name>George</name> 
       <rank>3</rank> 
      </Employee> 
      <Employee> 
       <name>Michael</name> 
       <rank>5</rank> 
      </Employee> 
      <Employee> 
       <name>Jeff</name> 
       <rank>1</rank> 
      </Employee> 
      <Employee> 
       <name>Todd</name> 
       <rank>7</rank> 
      </Employee> 
      <Employee> 
       <name>Jessica</name> 
       <rank>5</rank> 
      </Employee> 
     </Employees> 
    </Office> 
</Root> 

办公类:

import javax.xml.bind.annotation.*; 
import java.util.Vector; 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Office { 

    @XmlElementWrapper(name = "Employees") 
    @XmlElement(name = "Employee") 
    private Vector<Employee> employees; 

} 

Employee类:

import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlAccessType; 

@XmlAccessorType(XmlAccessType.FIELD) 
public class Employee { 

    @XmlElement(name="name") 
    private String name; 
    @XmlElement(name="rank") 
    private int rank; 


    public void promote() { 
     rank++; 
    } 

} 

Driv呃:

import javax.xml.stream.*; 
import javax.xml.bind.JAXBContext; 
import javax.xml.bind.JAXBException; 
import javax.xml.bind.Unmarshaller; 
import javax.xml.bind.Marshaller; 

import java.io.FileReader; 
public class Driver { 

    public static void main (String[] args) { 
     parseOffice(); 

    } 

    public static void parseOffice() { 
     try { 

      XMLInputFactory f = XMLInputFactory.newInstance(); 
      XMLStreamReader reader = f.createXMLStreamReader(new FileReader("Office.xml")); 

      JAXBContext context = JAXBContext.newInstance(Office.class); 
      Unmarshaller unmarshaller = context.createUnmarshaller(); 
      Office office = unmarshaller.unmarshal(reader, Office.class).getValue(); 

      Marshaller marshaller = context.createMarshaller(); 
      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
      marshaller.marshal(office, System.out); 

     } 
     catch (Exception e) { 
      e.printStackTrace(); 
     } 
     } 
} 
+0

我忽略输出,因为后是足够长的时间,它可以很容易被复制;但是,如果我需要包括它,我会这样做。 – Michael 2014-12-13 18:54:10

回答

3

你为什么不创建一个通用的根元素?

@XmlRootElement(name="Root" ...) 
public class Root { 
    @XmlAnyElement(lax=true) 
    private Object content; 
} 

将它添加到您的上下文和解组。你应该得到一个JAXBElement<Office>作为content

+1

好吧,显然我可以这样做 - 但那不是我想要的原因:如果可能,我想知道如何在不添加任何东西的情况下执行此操作。我需要一种方法来忽略或跳过根元素。我想,我应该在我的问题中提到它。 +1 – Michael 2014-12-13 19:15:16

+2

@Michael你必须在任何情况下添加一些东西。要么是额外的根元素映射,要么是较低级别的跳过代码。我会说一个额外的根类更好,因为它与其他映射相同,并与任何东西(SAX,StAX,DOM)一起工作。但是,您可能有技术上的原因(目前对我来说不透明),否则就想拥有它。然后在较低级别上执行 - 跳过StAX状态,过滤SAX事件,在DOM中进行预先潜水。 – lexicore 2014-12-13 19:40:36

+0

出于好奇,我如何将'content'对象转换为office对象?我可以这样做,因为Panther建议,但有一种简单的方法可以用更通用的方式进行转换吗? – Joseph 2016-01-21 18:55:35

1

只需添加层级的根类即可。并从Root类获取Office类。

根类: -

import javax.xml.bind.annotation.*; 
import java.util.Vector; 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Root { 


@XmlElement(name = "Office") 
private Office office; 
} 

办公室类

import javax.xml.bind.annotation.*; 
import java.util.Vector; 


    @XmlAccessorType(XmlAccessType.FIELD) 
    public class Office { 

    @XmlElementWrapper(name = "Employees") 
    @XmlElement(name = "Employee") 
    private Vector<Employee> employees; 

    } 

变化解析方法: -

 JAXBContext context = JAXBContext.newInstance(Root.class); 
     Unmarshaller unmarshaller = context.createUnmarshaller(); 
     Root root = unmarshaller.unmarshal(reader, Root.class).getValue(); 
     Office office = root.getOffice(); 
+0

您将内容限制在“Root”中的'Office',这是不灵活的。 – lexicore 2014-12-13 19:36:29

+0

@lexicore感谢您的输入,我只是想解决他的问题。由于他似乎不想做太多的改变 – Panther 2014-12-13 19:38:24

+0

没问题,只是一个提示。如果你是对的,我们的两条鱼都似乎不适合OP。有时候是这样的。 – lexicore 2014-12-13 19:42:04