2010-05-04 4 views
4

저는 webservices 클라이언트 응용 프로그램에서 일하고 있는데 대부분 작동합니다. 제 3 자 웹 서비스 벌금에서 데이터를 검색하고 읽을 수 있습니다. 이제 일부 데이터를 제출해야하며 막혔습니다.Java 객체를 XML 요소로 변환 하시겠습니까?

내가 검색하거나 제출하는 객체의 클래스는 xjc 도구를 통해 XSD 파일에서 생성되었습니다. 내가 붙어있는 부분은 그 객체들 중 하나를 XML 트리로 변환하여 웹 서비스에 제출하는 것입니다.

ws와의 요청을 검색/전송할 때 'payload'개체가 포함되어 있습니다.

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "PayloadType", propOrder = { 
    "compressed", 
    "document", 
    "any", 
    "format" 
}) 
public class PayloadType { 

    @XmlElement(name = "Compressed") 
    protected String compressed; 
    @XmlElement(name = "Document") 
    protected List<String> document; 
    @XmlAnyElement 
    protected List<Element> any; 
    protected String format; 

    public List<Element> getAny() { 
     if (any == null) { 
      any = new ArrayList<Element>(); 
     } 
     return this.any; 
    } 

} 

내가 XML 트리를 포함하는 '모든'필드와 걱정 유일한 필드 : 이것은 (부분 목록)로 자바 코드에 정의되어 있습니다. ws에서 데이터를 검색 할 때이 필드를 다음과 같이 읽습니다. ('root'는 org.w3c.dom.Element 유형이고 getAny(). get (0)을 호출 한 결과입니다. 페이로드 개체)

NodeList nl = root.getElementsByTagName("ns1:Process"); // "ns1:Process" is an XML node to do something with 
if (nl != null && nl.getLength() > 0) { 
    for (int i = 0; i < nl.getLength(); i++) { 
     Element proc = (Element) nl.item(i); 
     try { 
      // do something with the 'proc' Element here... 
     } catch (Exception ex) { 
      // handle problems here... 
     } 
    } 
} 

데이터 제출이 막혔습니다. 어떻게하면 XSD에서 생성 된 클래스 중 하나에서 생성 된 자바 객체를 가져 와서 'any'페이로드 객체 목록에 추가 할 수있는 Element 객체로 변환 할 수 있습니까? 예를 들어, 나는 DailyData 클래스를 가지고 있고 생성하고 데이터로 채울 경우 :

DailyData dData = new DailyData(); 
dData.setID = 34; 
dData.setValues = "3,5,76,23"; 

어떻게 페이로드 객체의 '어떤'목록에 그 '를 dData'객체를 추가하는 방법은 무엇입니까? 그것은 요소 여야합니다. JAXBContext marshaller로 무언가를합니까? 저는 XML 구조를 검사하기 위해 'dData'객체를 화면에 덤프하는 데 사용했습니다.

나는 그 대답이 얼굴에서 나를 응시하고 있다고 확신하지만 나는 그것을 볼 수 없다!

데이브

UPDATE :

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
Document doc = dbf.newDocumentBuilder().newDocument(); 

JAXBContext context = JAXBContext.newInstance(DailyData.class); 
Marshaller marshaller = context.createMarshaller(); 
marshaller.marshal(dData, doc); 


PayloadType payload = new PayloadType(); 
payload.getAny().add((Element)doc.getFirstChild()); 
+0

을 내가 생각 * * 나는 그것을 알아 낸하지만 수 DEV 환경에서 몇 가지 테스트 데이터가 나올 때까지 확실하게 알 수는 없을 것입니다. 정확하다고 밝혀지면 내 대답을 게시 할 것입니다. – DaveKub

+0

투표를했기 때문에 자신의 질문에 답을 해 주었으면합니다 :-) 가장 유용합니다. – rds

답변

1

스키마에서 이런 일이 때 List<Element> 필드 유형은 일반적으로 XJC에 의해 생성되는 데 도움이 될 것입니다

<xs:any processContents="skip" maxOccurs="unbounded" minOccurs="0" /> 

여기에있는 키는 processContents="skip"입니다. 이는 "무엇이든"이라는 뜻입니다. 올바른 형식의 XML이 여기에 들어갈 수 있습니다. 모든 XJC가 할 수있는 일은 무료이기 때문에이를 DOM으로 표현하는 것이므로 그 페이로드를 처리하는 것은 귀하의 책임이됩니다.

processContents="skip"을 제거하면 페이로드 XML을 JAXBContext의 클래스와 일치시킬 수있는 경우 JAXB는 페이로드를 객체 모델에 바인딩하려고 시도합니다. 이 경우 XJC는 List<Object> 유형의 필드를 생성합니다.(그것은 않는 경우 인식)

은 개선처럼 보이지 않을 수도 있지만합니다 ( JAXBContext 그것을 결합 할 수있는 무언가로 페이로드를 인식하지 못하는 경우)이 ListElement를 포함 할 수 있습니다, 또는 JAXBElement. 후자에는 바인딩 된 버전의 페이로드가 들어 있으며 처리하기가 훨씬 쉽습니다.

자세한 내용은 here입니다.

스키마를 수정할 수없고 processContents="skip"으로 붙어 있다면, 농구대를 뛰어 넘어야 할 것입니다. 당신은 당신의 페이로드 (payload) 클래스에 대해 알고 다른 JAXBContext 구축하고, marshaller.marshal(payload, new DOMResult()) 같은 것을 사용 (AN Element에 마샬링하는 것을 사용합니다. 그런 다음 페이로드에 해당 요소를 덤프 할 수 있습니다.

+0

설명에 감사 드리며 링크를 확인해 보겠습니다. XSD 파일은 제 3 자에 의해 제공되므로 변경하고 싶지 않습니다. 그래서, 농구대 점프입니다! 내가 해왔 던 방식은 당신의 제안과 비슷한 마샬링을 포함합니다. 내 코드는 오류없이 실행됩니다. 테스트는 '자신의'웹 서비스가 내가 보낸 것을 받아들이는지, 한 번 테스트 데이터가 그들의 시스템에서 사용 가능한지 확인하는 것입니다 ... – DaveKub

+1

제안대로 작동했습니다! 내 원래 질문의 맨 아래에 코드를 넣었습니다. – DaveKub

0

우선은, 모든 유형의 요소가 내부의 XML을 포함 할 수 있습니다 : 아래의 코드 조각 작업을 얻었다. 따라서 스키마 유효성 검사는 DailyData 클래스 XML 표현을 여기에 추가하더라도 잘 작동합니다.

이제 DailyData 클래스의 마샬링에 대한 다른 질문이 있습니다. 이 클래스가 xjc 컴파일러 자체를 사용하여 생성 된 경우이 클래스 (또는 다른 생성 된 클래스)는이 객체를 XML로 변환하는 방법을 이미 알고 있습니다.

내가 직접 사용하지 않은,하지만 다음 링크는 당신에게

http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/rwbs_xjc.html

관련 문제