JAXB解组XML文件

时间:2015-07-23 08:20:51

标签: java xml jaxb unmarshalling

我有以下XML文件:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:api="http://SDASolutions.com/API">
  <soapenv:Header/>
  <soapenv:Body>
    <api:LoginUser>
      <api:userId>user</api:userId>
      <api:userPassword>12345</api:userPassword>
      <api:utcTimeStamp>2015-05-12T17:43:52.957</api:utcTimeStamp>
    </api:LoginUser>
  </soapenv:Body>
</soapenv:Envelope>

此XML的类是:

public class LoginModel {
  @XmlAttribute
  private String userId;

  @XmlAttribute
  private String userPassword;

  public String getUserId() {
      return userId;
  }

  public void setUserId(String userId) {
      this.userId = userId;
  }

  public String getUserPassword() {
      return userPassword;
  }

  public String setUserPassword(Sttring userPassword) {
      this.userPassword = userPassword;
  }
}

我应该添加哪些其他注释以及哪里可以成功解组文件?(我也想忽略utcTimeStamp)

我有以下解组方法:

public static <T extends Object> T convertXML(String fileName, Class<T> tClass) throws JAXBException {
    File file = new File(fileName);
    JAXBContext jaxbContext = JAXBContext.newInstance(tClass);
    Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
    T tObject = (T) jaxbUnmarshaller.unmarshal(file);
    return tObject;
}

我的问题是如何在不解析XML的情况下跳过第一个标签。 我现在添加了根名称作为LoginUser,但我仍然需要能够跳过Envelope,Header和Body标签。

3 个答案:

答案 0 :(得分:0)

试试这个

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
 "userId","userPassword"
})
@XmlRootElement(name = "LoginUser")
public class LoginUser{

@XmlElement(name = "userId", required = true)
private String userId;


@XmlElement(name = "userPassword", required = true)
private String userPassword;

答案 1 :(得分:0)

我也不得不忽略项目中的时间戳。为此,我在Pojo类中为XML添加了setter和getter,当服务被命中时,我只需设置

<强> pojo.setTimeStamp(空);

答案 2 :(得分:0)

你的pojo类与xml不匹配。以下更正了一个:

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "LoginUser", namespace = "http://SDASolutions.com/API")
public class LoginUser{
    private String userId;
    private String userPassword;

    public String getUserId(){
        return userId;
    }

    @XmlElement(namespace = "http://SDASolutions.com/API")
    public void setUserId(String userId){
        this.userId = userId;
    }

    public String getUserPassword(){
        return userPassword;
    }

    @XmlElement(namespace = "http://SDASolutions.com/API")
    public void setUserPassword(String userPassword){
        this.userPassword = userPassword;
    }
}

下面是xml-filter,用于提取soap body中的元素:

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.NamespaceSupport;
import org.xml.sax.helpers.XMLFilterImpl;

import javax.xml.bind.JAXBContext;
import javax.xml.namespace.QName;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import java.util.Enumeration;
import java.util.List;

/**
 * @author Santhosh Kumar Tekuri
 */
public class SkipXMLFilter extends XMLFilterImpl{
    private QName qname;

    public SkipXMLFilter(XMLReader parent, QName qname){
        super(parent);
        this.qname = qname;
    }

    private boolean needNewContext;
    private NamespaceSupport nsSupport;
    private int depth;
    private boolean delegate;

    @Override
    public void startDocument() throws SAXException{
        nsSupport = new NamespaceSupport();
        needNewContext = true;
        depth = 0;
        delegate = false;
        super.startDocument();
    }

    @Override
    public void startPrefixMapping(String prefix, String uri) throws SAXException{
        if(needNewContext){
            nsSupport.pushContext();
            needNewContext = false;
        }
        nsSupport.declarePrefix(prefix, uri);
        if(delegate)
            super.startPrefixMapping(prefix, uri);
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException{
        if(needNewContext)
            nsSupport.pushContext();
        needNewContext = true;

        if(delegate)
            super.startElement(uri, localName, qName, atts);

        if(depth==0){
            if(qname.getNamespaceURI().equals(uri) && qname.getLocalPart().equals(localName)){
                depth++;
                delegate = true;
                Enumeration prefixes = nsSupport.getPrefixes();
                while(prefixes.hasMoreElements()){
                    String prefix = (String)prefixes.nextElement();
                    super.startPrefixMapping(prefix, nsSupport.getURI(prefix));
                }
            }
        }else
            depth++;

    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException{
        if(delegate)
            super.characters(ch, start, length);
    }

    @Override
    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException{
        if(delegate)
            super.ignorableWhitespace(ch, start, length);
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException{
        if(depth!=0){
            depth--;
            if(depth==1 && delegate){
                delegate = false;
                super.endElement(uri, localName, qName);
                Enumeration prefixes = nsSupport.getPrefixes();
                while(prefixes.hasMoreElements())
                    super.endPrefixMapping((String)prefixes.nextElement());
            }
        }
        if(delegate)
            super.endElement(uri, localName, qName);
        nsSupport.popContext();
    }

    @Override
    public void endPrefixMapping(String prefix) throws SAXException{
        if(delegate)
            super.endPrefixMapping(prefix);
    }
}

现在使用jaxb阅读,使用以下方法:

public static <T extends Object> T convertXML(String fileName, Class<T> tClass) throws Exception{
    SAXParserFactory factory = SAXParserFactory.newInstance();
    factory.setNamespaceAware(true);
    SkipXMLFilter reader = new SkipXMLFilter(factory.newSAXParser().getXMLReader(), new QName("http://schemas.xmlsoap.org/soap/envelope/", "Body"));
    InputSource is = new InputSource(fileName);
    JAXBContext jaxbContext = JAXBContext.newInstance(tClass);
    return (T)jaxbContext.createUnmarshaller().unmarshal(new SAXSource(reader, is));
}