10
votes

I am trying to unmarshal the XML file.I created the Jaxb classes but when i try to unmarshal,it gives me :

Exception in thread "main" javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"processedSalesOrderTypeList"). Expected elements are <{api.supplieroasis.com}processedSalesOrderMessage>,<{api.supplieroasis.com}salesOrderMessage>,<{api.supplieroasis.com}shipperOfRecordAccountNumber>,<{api.supplieroasis.com}shippingAccountNumber>,<{api.supplieroasis.com}uspsMailerId>,<{api.supplieroasis.com}warehouseName>

This is my ObjectFactory.java class :

@XmlRegistry
public class ObjectFactory {

    private final static QName _ProcessedSalesOrderMessage_QNAME = new QName("api.supplieroasis.com", "processedSalesOrderMessage");
    private final static QName _WarehouseName_QNAME = new QName("api.supplieroasis.com", "warehouseName");
    private final static QName _ShippingAccountNumber_QNAME = new QName("api.supplieroasis.com", "shippingAccountNumber");
    private final static QName _ShipperOfRecordAccountNumber_QNAME = new QName("api.supplieroasis.com", "shipperOfRecordAccountNumber");
    private final static QName _SalesOrderMessage_QNAME = new QName("api.supplieroasis.com", "salesOrderMessage");
    private final static QName _UspsMailerId_QNAME = new QName("api.supplieroasis.com", "uspsMailerId");
}

XSD:

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="api.example.com" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="salesChannelOrderNumber" type="xs:string"/>
  <xs:element name="salesChannelName" type="xs:string"/>
  <xs:element name="orderDate" type="xs:dateTime"/>
  <xs:element name="sofsCreatedDate" type="xs:dateTime"/>
  <xs:element name="warehouseName">
    <xs:complexType>
      <xs:sequence>
        <xs:element type="xs:string" name="code"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="shipToAddress">
    <xs:complexType>
      <xs:sequence>
        <xs:element type="xs:string" name="contactName"/>
        <xs:element type="xs:string" name="address1"/>
        <xs:element type="xs:string" name="city"/>
        <xs:element type="xs:string" name="stateOrProvince"/>
        <xs:element type="xs:int" name="postalCode"/>
        <xs:element type="xs:string" name="countryCode"/>
        <xs:element type="xs:string" name="phone"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="returnAddress">
    <xs:complexType>
      <xs:sequence>
        <xs:element type="xs:string" name="contactName"/>
        <xs:element type="xs:string" name="address1"/>
        <xs:element type="xs:string" name="city"/>
        <xs:element type="xs:string" name="stateOrProvince"/>
        <xs:element type="xs:int" name="postalCode"/>
        <xs:element type="xs:string" name="countryCode"/>
        <xs:element type="xs:string" name="phone"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="shippingSpecifications">
    <xs:complexType>
      <xs:sequence>
        <xs:element type="xs:string" name="isThirdPartyBilling"/>
        <xs:element type="xs:string" name="isSignatureRequired"/>
        <xs:element type="xs:string" name="isDeclaredValueRequired"/>
        <xs:element name="smallParcelShipment">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="shippingServiceLevel">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element type="xs:string" name="code"/>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element type="xs:string" name="isExport"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="branding" type="xs:string"/>
  <xs:element name="orderFulfillment" type="xs:string"/>
  <xs:element name="orderId" type="xs:int"/>
  <xs:element name="status" type="xs:string"/>
  <xs:element name="retailChannelCode" type="xs:string"/>
  <xs:element name="retailerOrderCode" type="xs:string"/>
  <xs:element name="retailOrderNumber" type="xs:int"/>
  <xs:element name="actionRequired" type="xs:string"/>
  <xs:element name="processedSalesOrderLine">
    <xs:complexType>
      <xs:sequence>
        <xs:element type="xs:byte" name="salesChannelLineId"/>
        <xs:element type="xs:byte" name="salesChannelLineNumber"/>
        <xs:element type="xs:string" name="partnerSKU"/>
        <xs:element type="xs:string" name="barcode"/>
        <xs:element type="xs:string" name="salesChannelSKU"/>
        <xs:element type="xs:byte" name="quantity"/>
        <xs:element type="xs:float" name="itemPrice"/>
        <xs:element type="xs:int" name="lineId"/>
        <xs:element type="xs:int" name="itemId"/>
        <xs:element type="xs:string" name="itemName"/>
        <xs:element type="xs:string" name="lineStatus"/>
        <xs:element type="xs:float" name="unitCost"/>
        <xs:element type="xs:string" name="unitCostCurrencyCode"/>
        <xs:element type="xs:float" name="firstCost" minOccurs="0"/>
        <xs:element type="xs:string" name="firstCostCurrencyCode" minOccurs="0"/>
        <xs:element type="xs:float" name="additionalShippingCost" minOccurs="0"/>
        <xs:element type="xs:string" name="additionalShippingCostCurrencyCode" minOccurs="0"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

XML file to parse:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<processedSalesOrderTypeList xmlns:ns2="api.example.com">
    <totalCount>4</totalCount>
    <list>
        <ns2:salesChannelOrderNumber>17456-1</ns2:salesChannelOrderNumber>
        <ns2:salesChannelName>OSTK</ns2:salesChannelName>
        <ns2:orderDate>2017-02-09T13:25:59.000-07:00</ns2:orderDate>
        <ns2:sofsCreatedDate>2017-02-09T09:40:19.000-07:00</ns2:sofsCreatedDate>
        <ns2:warehouseName>
            <ns2:code>Avia Warehouse</ns2:code>
        </ns2:warehouseName>
        <ns2:shipToAddress>
            <ns2:contactName>TestOrder1</ns2:contactName>
            <ns2:address1>5961 Adam Street</ns2:address1>
            <ns2:city>Salt Lake City</ns2:city>
            <ns2:stateOrProvince>UT</ns2:stateOrProvince>
            <ns2:postalCode>84047</ns2:postalCode>
            <ns2:countryCode>US</ns2:countryCode>
            <ns2:phone>801-555-5961</ns2:phone>
        </ns2:shipToAddress>
        <ns2:returnAddress>
            <ns2:contactName>Joe User-1355</ns2:contactName>
            <ns2:address1>1355 Adam Street</ns2:address1>
            <ns2:city>Salt Lake City</ns2:city>
            <ns2:stateOrProvince>UT</ns2:stateOrProvince>
            <ns2:postalCode>84047</ns2:postalCode>
            <ns2:countryCode>US</ns2:countryCode>
            <ns2:phone>801-555-1355</ns2:phone>
        </ns2:returnAddress>
        <ns2:shippingSpecifications>
            <ns2:isThirdPartyBilling>false</ns2:isThirdPartyBilling>
            <ns2:isSignatureRequired>false</ns2:isSignatureRequired>
            <ns2:isDeclaredValueRequired>false</ns2:isDeclaredValueRequired>
            <ns2:smallParcelShipment>
                <ns2:shippingServiceLevel>
                    <ns2:code>GROUND</ns2:code>
                </ns2:shippingServiceLevel>
            </ns2:smallParcelShipment>
            <ns2:isExport>false</ns2:isExport>
        </ns2:shippingSpecifications>
        <ns2:branding/>
        <ns2:orderFulfillment>ALLOW_PARTIAL_FILL</ns2:orderFulfillment>
        <ns2:orderId>50048</ns2:orderId>
        <ns2:status>PROCESSING</ns2:status>
        <ns2:retailChannelCode>OSTK_1716</ns2:retailChannelCode>
        <ns2:retailerOrderCode>OrderCode-123459790</ns2:retailerOrderCode>
        <ns2:retailOrderNumber>123459790</ns2:retailOrderNumber>
        <ns2:actionRequired>true</ns2:actionRequired>
        <ns2:processedSalesOrderLine>
            <ns2:salesChannelLineId>1</ns2:salesChannelLineId>
            <ns2:salesChannelLineNumber>1</ns2:salesChannelLineNumber>
            <ns2:partnerSKU>GPI42829404</ns2:partnerSKU>
            <ns2:barcode>GPI42829404</ns2:barcode>
            <ns2:salesChannelSKU>GPI42829404</ns2:salesChannelSKU>
            <ns2:quantity>1</ns2:quantity>
            <ns2:itemPrice>81.98</ns2:itemPrice>
            <ns2:lineId>58838</ns2:lineId>
            <ns2:itemId>217412</ns2:itemId>
            <ns2:itemName>Altimair TPU Camping Airmat with Built-in Foot Pump</ns2:itemName>
            <ns2:lineStatus>PROCESSING</ns2:lineStatus>
            <ns2:unitCost>0.00</ns2:unitCost>
            <ns2:unitCostCurrencyCode>USD</ns2:unitCostCurrencyCode>
            <ns2:firstCost>41.60</ns2:firstCost>
            <ns2:firstCostCurrencyCode>USD</ns2:firstCostCurrencyCode>
            <ns2:additionalShippingCost>0.00</ns2:additionalShippingCost>
            <ns2:additionalShippingCostCurrencyCode>USD</ns2:additionalShippingCostCurrencyCode>
        </ns2:processedSalesOrderLine>
    </list>
</processedSalesOrderTypeList>

Can you please help as i am stuck and not able to provide my Client reason for the delay in developing this functionality.

Thanks, Jayesh Jain

4
there is no processedSalesOrderTypeList in your xsd ...Plirkee
@Plirkee - Yes,i know it is not there in the XSD,but when i received the XML response this tag is there. I tried creating the XSD from the XML and then generated the JaxB classes from the new XSD,still it didnt worked. Can you also check by generating the JaxB classes from XML and let me know,i am exhausted with all the suggestion from friends and colleagues.Jayesh
@Jayesh This can be resolved. But please provide the xsd with processedSalesOrderTypeList defined (generated), and the generated Java class for processedSalesOrderTypeList . The root element needs to have proper namespace.Optional

4 Answers

5
votes

I can think of 2 different reasons why your Unmarshaller is failing.

  1. Looking in your schema, "processedSalesOrderTypeList" is not defined. In the error you mentioned, the valid elements are:

<{api.supplieroasis.com}processedSalesOrderMessage>,<{api.supplieroasis.com}salesOrderMessage>,<{api.supplieroasis.com}shipperOfRecordAccountNumber>,<{api.supplieroasis.com}shippingAccountNumber>,<{api.supplieroasis.com}uspsMailerId>, <{api.supplieroasis.com}warehouseName>

The XML namespace is contained within the braces {} and the element name comes right after it. These values are specified in your ObjectFactory. As you can see, since "processedSalesOrderTypeList" is not defined within your ObjectFactory so when the Unmarshaller encounters the "processedSalesOrderTypeList" element in your XML, it has no idea how to process it.

  1. I've had an issue with the namespaces mismatching in code generated from xjc which caused a lot of the elements to return null during deserialization. The strange thing was some of the elements would be correctly parsed but some wouldn't. First I would add a ValidationEventHandler to see all XML validation errors:

    unmarshaller.setEventHandler(new DefaultValidationEventHandler());

Then, if you get an error similar to the one below, this answer should help you.

unexpected element (uri:"", local:"MyEntity")

I would look for the class which has this field (it could be a root-level class). Use judgement in finding this class, if the element tag it is failing to parse is the root element then most likely the class has the same exact name as the element. If the element is a child of another element, look in the respective class for that particular element.

Once you locate the class, look to see that the namespaces match up correctly. I've had an issue where the namespace was blank and needed to be filled in.

Fill in the namespace with the same namespace that the XML has. Code Example:

<test:MyEntity xmlns:test="com.example">
...
</test:MyEntity>

@XmlElement(name = "MyEntity", namespace = "test:com.example")

In essence, make sure the namespace in the annotation and the XML are matching, if not and namespace verification is enabled it will refuse to unmarshal the XML.

If this does not fix your problem and you see an exception regarding ObjectFactory, I would look for the QName that corresponds to this particular element. The correct snippet of code should something like this, making sure the namespaces are matching (create it if it does not exist):

QName _MyEntity_QNAME = new QName("test:com.example", "MyEntity");

In the same ObjectFactory, look for the @XmlElementDecl. This is the annotation that defines how the XML element is converted into a Java object. The correct code should look something like this:

@XmlElementDecl(namespace = "test:com.example", name = "MyEntity")
public JAXBElement<MyEntity> createMyEntity(MyEntity value) {
    return new JAXBElement<MyEntity>(_MyEntity_QNAME, MyEntity.class, null, value);
}

After the namespaces all match up, deserialization should work. If not, go back and check for the exception and post it and I will provide some more insight.

2
votes

Your JAXB object factory and XSD seems to be different..try recreating the JAXB classes again.

2
votes

Your XSD doesn't match XML. But you can create new XSD from XML. I use trang utility. It is better to provide many XMLs to generate all elements.

I saved your XML to 1.xml, ran:

trang 1.xml 1.xsd

download link

Then you can create java classes with openjdk native utility

xjc -d /tmp/zzz 1.xsd

your classes will appear in /tmp/zzz

0
votes

Try using this XSD to generate the Java classes, this should work, I tried and able to unmarshall the xml you sententer image description here

<?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="api.example.com" xmlns:ns2="api.example.com">
      <xs:element name="processedSalesOrderTypeList">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="ns2:totalCount"/>
            <xs:element ref="ns2:list"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="totalCount" type="xs:integer"/>
      <xs:element name="list">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="ns2:salesChannelOrderNumber"/>
            <xs:element ref="ns2:salesChannelName"/>
            <xs:element ref="ns2:orderDate"/>
            <xs:element ref="ns2:sofsCreatedDate"/>
            <xs:element ref="ns2:warehouseName"/>
            <xs:element ref="ns2:shipToAddress"/>
            <xs:element ref="ns2:returnAddress"/>
            <xs:element ref="ns2:shippingSpecifications"/>
            <xs:element ref="ns2:branding"/>
            <xs:element ref="ns2:orderFulfillment"/>
            <xs:element ref="ns2:orderId"/>
            <xs:element ref="ns2:status"/>
            <xs:element ref="ns2:retailChannelCode"/>
            <xs:element ref="ns2:retailerOrderCode"/>
            <xs:element ref="ns2:retailOrderNumber"/>
            <xs:element ref="ns2:actionRequired"/>
            <xs:element ref="ns2:processedSalesOrderLine"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="salesChannelOrderNumber" type="xs:NMTOKEN"/>
      <xs:element name="salesChannelName" type="xs:NCName"/>
      <xs:element name="orderDate" type="xs:NMTOKEN"/>
      <xs:element name="sofsCreatedDate" type="xs:NMTOKEN"/>
      <xs:element name="warehouseName" type="ns2:code"/>
      <xs:element name="shipToAddress">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="ns2:contactName"/>
            <xs:element ref="ns2:address1"/>
            <xs:element ref="ns2:city"/>
            <xs:element ref="ns2:stateOrProvince"/>
            <xs:element ref="ns2:postalCode"/>
            <xs:element ref="ns2:countryCode"/>
            <xs:element ref="ns2:phone"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="returnAddress">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="ns2:contactName"/>
            <xs:element ref="ns2:address1"/>
            <xs:element ref="ns2:city"/>
            <xs:element ref="ns2:stateOrProvince"/>
            <xs:element ref="ns2:postalCode"/>
            <xs:element ref="ns2:countryCode"/>
            <xs:element ref="ns2:phone"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="shippingSpecifications">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="ns2:isThirdPartyBilling"/>
            <xs:element ref="ns2:isSignatureRequired"/>
            <xs:element ref="ns2:isDeclaredValueRequired"/>
            <xs:element ref="ns2:smallParcelShipment"/>
            <xs:element ref="ns2:isExport"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="isThirdPartyBilling" type="xs:boolean"/>
      <xs:element name="isSignatureRequired" type="xs:boolean"/>
      <xs:element name="isDeclaredValueRequired" type="xs:boolean"/>
      <xs:element name="smallParcelShipment">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="ns2:shippingServiceLevel"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="shippingServiceLevel" type="ns2:code"/>
      <xs:element name="isExport" type="xs:boolean"/>
      <xs:element name="branding">
        <xs:complexType/>
      </xs:element>
      <xs:element name="orderFulfillment" type="xs:NCName"/>
      <xs:element name="orderId" type="xs:integer"/>
      <xs:element name="status" type="xs:NCName"/>
      <xs:element name="retailChannelCode" type="xs:NCName"/>
      <xs:element name="retailerOrderCode" type="xs:NCName"/>
      <xs:element name="retailOrderNumber" type="xs:integer"/>
      <xs:element name="actionRequired" type="xs:boolean"/>
      <xs:element name="processedSalesOrderLine">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="ns2:salesChannelLineId"/>
            <xs:element ref="ns2:salesChannelLineNumber"/>
            <xs:element ref="ns2:partnerSKU"/>
            <xs:element ref="ns2:barcode"/>
            <xs:element ref="ns2:salesChannelSKU"/>
            <xs:element ref="ns2:quantity"/>
            <xs:element ref="ns2:itemPrice"/>
            <xs:element ref="ns2:lineId"/>
            <xs:element ref="ns2:itemId"/>
            <xs:element ref="ns2:itemName"/>
            <xs:element ref="ns2:lineStatus"/>
            <xs:element ref="ns2:unitCost"/>
            <xs:element ref="ns2:unitCostCurrencyCode"/>
            <xs:element ref="ns2:firstCost"/>
            <xs:element ref="ns2:firstCostCurrencyCode"/>
            <xs:element ref="ns2:additionalShippingCost"/>
            <xs:element ref="ns2:additionalShippingCostCurrencyCode"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="salesChannelLineId" type="xs:integer"/>
      <xs:element name="salesChannelLineNumber" type="xs:integer"/>
      <xs:element name="partnerSKU" type="xs:NCName"/>
      <xs:element name="barcode" type="xs:NCName"/>
      <xs:element name="salesChannelSKU" type="xs:NCName"/>
      <xs:element name="quantity" type="xs:integer"/>
      <xs:element name="itemPrice" type="xs:decimal"/>
      <xs:element name="lineId" type="xs:integer"/>
      <xs:element name="itemId" type="xs:integer"/>
      <xs:element name="itemName" type="xs:string"/>
      <xs:element name="lineStatus" type="xs:NCName"/>
      <xs:element name="unitCost" type="xs:decimal"/>
      <xs:element name="unitCostCurrencyCode" type="xs:NCName"/>
      <xs:element name="firstCost" type="xs:decimal"/>
      <xs:element name="firstCostCurrencyCode" type="xs:NCName"/>
      <xs:element name="additionalShippingCost" type="xs:decimal"/>
      <xs:element name="additionalShippingCostCurrencyCode" type="xs:NCName"/>
      <xs:complexType name="code">
        <xs:sequence>
          <xs:element ref="ns2:code"/>
        </xs:sequence>
      </xs:complexType>
      <xs:element name="code" type="xs:string"/>
      <xs:element name="contactName" type="xs:string"/>
      <xs:element name="address1" type="xs:string"/>
      <xs:element name="city" type="xs:string"/>
      <xs:element name="stateOrProvince" type="xs:NCName"/>
      <xs:element name="postalCode" type="xs:integer"/>
      <xs:element name="countryCode" type="xs:NCName"/>
      <xs:element name="phone" type="xs:NMTOKEN"/>
    </xs:schema>