【问题标题】:Unmarshalling XML using JAXB2 returns null lists (Scala)使用 JAXB2 解组 XML 返回空列表 (Scala)
【发布时间】:2014-02-28 23:48:16
【问题描述】:

我正在使用 JAXB2 将我的 XML 字符串解组为一个名为 AccountInfo 的 java 对象。 AccountInfo 包含一个 accountID 和一个 Location 对象列表。目前我可以从 xml 中提取 acountID,但我的位置列表始终为空。任何帮助将不胜感激!谢谢!

这是我试图解组的 xml:

<AccountInfo AccountID="640480">
  <Location LocationID="1490075"/>
  <Location LocationID="8900561"/>
  <Location LocationID="2367782"/>
  <Location LocationID="2226598"/>
</AccountInfo>

我的 AccountInfo 架构(它会自动生成我的 java 对象):

<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.cspire.com/omnia/schema" xmlns:tns="http://www.cspire.com/omnia/schema"
elementFormDefault="qualified">

<xsd:element name="AccountInfo">
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element name="Location" type="tns:Location" minOccurs="0" maxOccurs="unbounded" />
    </xsd:sequence>
    <xsd:attribute name="AccountID" type="xsd:string"></xsd:attribute>
  </xsd:complexType>
</xsd:element>

<xsd:complexType name="Location">
  <xsd:attribute name="LocationID" type="xsd:string" />
</xsd:complexType>

</schema>

(部分)AccountInfo.java

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {"location"})
@XmlRootElement(name = "AccountInfo")
public class AccountInfo implements Equals, HashCode, ToString
{

  @XmlElement(name = "Location")
  protected List<Location> location;
  @XmlAttribute(name = "AccountID")
  protected String accountID;

  public AccountInfo() {
    super();
  }

  public AccountInfo(final List<Location> location, final String accountID) {
    this.location = location;
    this.accountID = accountID;
  }

  public List<Location> getLocation() {
    if (location == null) {
        location = new ArrayList<Location>();
    }
    return this.location;
  }

  public String getAccountID() {
    return accountID;
  }

  public void setAccountID(String value) {
    this.accountID = value;
  }

(部分)Location.java

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Location")
public class Location implements Equals, HashCode, ToString
{
  @XmlAttribute(name = "LocationID")
  protected String locationID;

  public Location() {
    super();
  }

  public Location(final String locationID) {
    this.locationID = locationID;
  }

  public String getLocationID() {
    return locationID;
  }

  public void setLocationID(String value) {
    this.locationID = value;
  }

我的主要对象:

object Main extends App {
  val xml = <string xmlns="http://schemas.martin-group.com/openomnia">&lt;AccountInfo AccountID="640480"&gt;&lt;Location LocationID="1490075"/&gt;&lt;Location LocationID="8900561"/&gt;&lt;Location LocationID="2367782"/&gt;&lt;Location LocationID="2226598"/&gt;&lt;/AccountInfo&gt;</string>
  val testXML = xml \\ "string" text

  val jc = JAXBContext.newInstance(classOf[AccountInfo])
  val unmarshaller = jc.createUnmarshaller
  val result = unmarshaller.unmarshal(new StreamSource(new StringReader(testXML), classOf[AccountInfo]).getValue

  println(result)
  println("Account ID: " + result.getAccountID)
  println(result.getLocation.isEmpty)
}

结果:

com.cspire.omnia.schema.AccountInfo@74c3d5ab[location=<null>, accountID=640480]
Account ID: 640480
true

【问题讨论】:

  • 可能想要关闭 com 部分以保持匿名。另外,嗨!

标签: java xml scala unmarshalling jaxb2


【解决方案1】:

我正在获取位置列表 - 这是代码。

 String xml ="" + 
               "  <AccountInfo xmlns=\"http://www.cspire.com/omnia/schema\" AccountID=\"640480\"> " + 
               "    <Location LocationID=\"1490075\"/> " + 
               "    <Location LocationID=\"8900561\"/> " + 
               "    <Location LocationID=\"2367782\"/> " + 
               "    <Location LocationID=\"2226598\"/> " + 
               "  </AccountInfo> " + 
               "";

    try {

          String testXML = xml ;
          ByteArrayInputStream inputXml = new ByteArrayInputStream (testXML.getBytes());
          JAXBContext jc = JAXBContext.newInstance(AccountInfo.class);
          Unmarshaller  unmarshaller = jc.createUnmarshaller();
          AccountInfo result;
         result = (AccountInfo) unmarshaller.unmarshal(inputXml);


         System.out.println("Account ID: " + result.getAccountID());
         System.out.println(result.getLocation().size());

         for(Location loc: result.getLocation()){
             System.out.println(loc.getLocationID());
         }


    } catch (JAXBException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 

输出:

    Account ID: 640480
    4
    1490075

    8900561

    2367782

    2226598

【讨论】:

    【解决方案2】:

    正在尝试解组的文档与您的 XML 架构不匹配。

    <AccountInfo AccountID="640480">
      <Location LocationID="1490075"/>
      <Location LocationID="8900561"/>
      <Location LocationID="2367782"/>
      <Location LocationID="2226598"/>
    </AccountInfo>
    

    要使其匹配 XML 架构(参见 targetNamespaceelementFormDefault 属性)和您的 JAXB 映射(参见 package-info 类上的 @XmlSchema 注释),您需要声明命名空间信息。

    <AccountInfo xmlns="http://www.cspire.com/omnia/schema" AccountID="640480">
      <Location LocationID="1490075"/>
      <Location LocationID="8900561"/>
      <Location LocationID="2367782"/>
      <Location LocationID="2226598"/>
    </AccountInfo>
    

    调试提示

    当您无法让 JAXB 解组 XML 文档时,请尝试填充对象模型并将其编组以查看 JAXB 期望的 XML 文档。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-01
      • 2013-03-06
      • 1970-01-01
      相关资源
      最近更新 更多