【问题标题】:JAXB unmarshal XML fileJAXB 解组 XML 文件
【发布时间】:2015-07-23 08:20:50
【问题描述】:

我有以下 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 标签。

【问题讨论】:

  • 请分享您到目前为止所尝试的内容,然后解释确切的问题,然后有人可以帮助您。请参阅此链接以获取asking proper questions
  • 你在类名上方使用过@xmlrootelement吗?如果您添加如何实现解组。我们可以找出问题所在。
  • 我更新了问题。

标签: java xml jaxb unmarshalling


【解决方案1】:

试试这个

@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;

【讨论】:

    【解决方案2】:

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

    pojo.setTimeStamp(null);

    【讨论】:

      【解决方案3】:

      您的 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;
          }
      }
      

      下面是提取soap body中元素的xml过滤器:

      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));
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-23
        • 2015-08-20
        • 2013-11-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多