2009-11-17 3 views
4

나는 이베이의 LMS (대형 가맹점 서비스)와 함께 일하고 있어요 및 오류로 실행 보관 :정렬 할 때 JAXB의 요소에 네임 스페이스 특성을 추가하려면 어떻게해야합니까?

org.xml.sax.SAXException: SimpleDeserializer encountered a child element, which is NOT expected, in something it was trying to deserialize.

후 시행 착오의 작정 내가 문제를 추적. 이 동안

<?xml version="1.0" encoding="UTF-8"?> 
<BulkDataExchangeRequests xmlns="urn:ebay:apis:eBLBaseComponents"> 
    <Header> 
    <Version>583</Version> 
    <SiteID>0</SiteID> 
    </Header> 
    <AddFixedPriceItemRequest xmlns="urn:ebay:apis:eBLBaseComponents"> 

(제가 보내고 한 것은)하지 않습니다 :

<?xml version="1.0" encoding="UTF-8"?> 
<BulkDataExchangeRequests xmlns="urn:ebay:apis:eBLBaseComponents"> 
    <Header> 
    <Version>583</Version> 
    <SiteID>0</SiteID> 
    </Header> 
    <AddFixedPriceItemRequest> 

차이가 AddFixedPriceItemRequest에 XML 네임 스페이스 속성입니다 그것은이 작품 밝혀졌습니다. 모든 XML은 현재 JAXB를 통해 마샬링되고 있으며, 두 번째 xmlns 특성을 내 파일의 다른 요소에 추가하는 가장 좋은 방법은 무엇인지 모르겠습니다.

그래서 질문입니다. JAXB의 다른 요소에 xmlns 속성을 추가하려면 어떻게합니까?

UPDATE : 요청에 의해

package ebay.apis.eblbasecomponents; 

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

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "AddFixedPriceItemRequestType", propOrder = { 
    "item" 
}) 
public class AddFixedPriceItemRequestType 
    extends AbstractRequestType 
{ 

    @XmlElement(name = "Item") 
    protected ItemType item; 

    public ItemType getItem() { 
     return item; 
    } 

    public void setItem(ItemType value) { 
     this.item = value; 
    } 
} 

추가 된 클래스 정의.

UPDATE 2 : 상기 클래스에 아무런 영향과 같이 편집 :

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(namespace = "urn:ebay:apis:eBLBaseComponents", 
name = "AddFixedPriceItemRequestType", propOrder = { 
    "item" 
}) 
public class AddFixedPriceItemRequestType 

UPDATE 3 : 여기 BulkDataExchangeRequestsType 클래스의 단편이다. AddFixedPriceItemRequest에 대해 @XmlElement에 namespace="urn:ebay:apis:eBLBaseComponents"을 던지려고했지만 아무 것도하지 않았습니다.

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "BulkDataExchangeRequestsType", propOrder = { 
    "header", 
    "addFixedPriceItemRequest" 
}) 
public class BulkDataExchangeRequestsType { 

    @XmlElement(name = "Header") 
    protected MerchantDataRequestHeaderType header; 
    @XmlElement(name = "AddFixedPriceItemRequest") 
    protected List<AddFixedPriceItemRequestType> addFixedPriceItemRequest; 

업데이트 4 : 다음은 마샬링 후 XML을 업데이트하는 코드의 끔찍한 덩어리입니다. 비록 내가 특히 그것을 자랑스럽게 생각하지는 않지만 이것은 현재 작동 중이다.

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    dbf.setNamespaceAware(true); 
    DocumentBuilder db = dbf.newDocumentBuilder(); 
    Document doc = db.newDocument(); 
    marshaller.marshal(request, doc); 
    NodeList nodes = doc.getChildNodes(); 
    nodes = nodes.item(0).getChildNodes(); 
    for(int i = 0; i < nodes.getLength(); i++){ 
     Node node = nodes.item(i); 
     if (!node.getNodeName().equals("Header")){ 
      ((Element)node).setAttribute("xmlns", "urn:ebay:apis:eBLBaseComponents"); 
     } 
    } 

모두에게 도움을 주셔서 감사합니다. 당신은 단지 일부 특정 경우에 네임 스페이스를 지정하려면

+0

"JAXB를 통해 생성"이란 정확히 무엇을 의미합니까? AddFixedPriceItemRequest 클래스의 정의를 추가 할 수 있습니까? –

+0

XML을 생성하기 위해 JAXB를 통해 마샬링을 사용하고 있습니다. BulkDataExchangeRequestsType 클래스에 xmlns 특성을 추가하는 특정 태그를 볼 수 없습니다. AddFixedPriceItemRequestType 클래스 정의를 질문에 추가했습니다. –

+0

왜 WSDL에 지정된 스키마를 aginst 생성하지 않습니까? http://developer.ebay.com/webservices/bulk-data-exchange/latest/BulkDataExchangeService.wsdl –

답변

5

, 당신의 XML 조각은 의미 상 동일합니다. AddFixedPriceItemRequest 요소의 xmlns 특성은 부모 요소의 네임 스페이스를 암시 적으로 상속하므로 중복됩니다. JAXB는이를 알고 있으므로 AddFixedPriceItemRequest에 네임 스페이스를 추가하는 것을 방해하지 않습니다. 단지 필요하지 않습니다.

이베이 서버가 AddFixedPriceItemRequestxmlns이 존재할 때만 작동하는 경우 깨지고 XML 및 스키마에서 요구하는 것 이상으로 입력이 요구됩니다. 이것이 실제로 가능하다면 (믿을 수는 없지만 가능하다면), JAXB와 같은 Java XML 문서 모델을 사용하는 것은 어려운 일이 될 것입니다. XML이 XML 인 것으로 가정하기 때문입니다. xmlns 선언을 가져 오는 요소에 대한 저수준의 방귀는 필요하지 않아야하므로 API에 노출되지 않습니다.

아무도 당신을 돕지 않습니다. 내 접근 방식은 Marshaller에 전달 된 DOMResult을 사용하여 DOM 객체에 JAXB 모델을 마샬링 한 다음 DOM의 수동 조정을 수행하여 xmlns을 적절한 위치에서 문서에 적용 할 수 있는지 확인하는 것입니다. 그런 다음 해당 DOM을 XML로 직렬화하여 보낼 수 있습니다.

이렇게하면 안되며 다른 곳에서 뭔가 잘못하고있는 것 같습니다. 이것은 ebay 웹 서비스가 이와 같이 부러지는 것보다 더 가능성이 높습니다.


편집 : 다음은 JAXB-to-DOM-to-XML 솔루션보다 약간 덜 끔찍한 제안입니다. 요청 XML이 숫자/문자열 값만 변경되면서 구조적으로 정적 인 경우이를 문자열 템플리트로 정의한 다음 런타임에 값을 바꾸고 보냅니다. 그런 다음 JAXB를 사용하여 결과를 해석 할 수 있습니다. 필자는 자바 XML 라이브러리를 부적절하게 어렵게 만드는 것을 설득 할 때 매우 정확한 네임 스페이스 접두사를 요구하는 웹 서비스를 통해 이것을 수행했습니다.

+0

네 말이 맞아. 전혀 이해가 안되지만, 똑같은 파일을 보낸다. (LMS 서비스는 기본적으로 주변에있을 때 파일을 업로드해야한다.) 추가 xmlns의 한 변경. 그것 없이는 서비스는 매번 "실패"를 반환합니다. 그것이있을 때 그 문제는 없습니다. 나는 더 쉬운 방법이 있기를 바랐다. DOM을 통해 드래그하는 것은 정말 번거롭기는하지만,이 시점에서 어떤 해결책이 짐승이 될지를 알 수있다. –

+0

대안을위한 편집보기 – skaffman

+0

불행히도 그 내용을 만드는 방법이 다소 역동적 일 수 있으므로 아마 작동하지 않을 것입니다. 그것이 좋았던 생각은 그렇습니다. –

3

봅니다 클래스 주석

@XmlType(namespace="urn:ebay:apis:eBLBaseComponents") 

또는

@XmlElement(namespace="urn:ebay:apis:eBLBaseComponents") 

속성 주석을 사용하는

지금까지 내가 말할 수있는
3

생성 된 클래스의 필드에 @XmlElement 주석이 누락되어 있는지 확인하고 존재하는 경우 네임 스페이스 속성이 누락되어 있는지 확인하십시오. 마샬링 된 XML의 모든 요소에 대해 네임 스페이스 접두사를 가져 오려면이 두 가지가 있어야합니다.

관련 문제