2012-09-20 2 views
2

이 주제와 관련된 모든 질문을 검색했지만 대답을 찾지 못했습니다. XML 문서를 자바 객체로 변환하려고합니다. 같은 작업을 수행 할 옵션을 검색 한 후 jaxb가 동일한 옵션을 수행 할 수있는 최상의 옵션임을 알게되었습니다. 나는 많은 기사를 언급하고 작동하지 않는이 해결책을 생각해 냈다. 누군가가 나를 도울 수 있습니까?XML에서 Java 객체로

XML 국방부 :

<Vectors> 
    <Vector> 
     <Id>1</Id> 
     <Name>abc</Name> 
     <Desc>abcdefg</Desc> 
     <Type>body</Type> 
     <Snippet> 
      <![CDATA[<total>1234</total>]]> 
     </Snippet> 
    </Vector> 
    <Vector> 
     <Id>2</Id> 
     <Name>def</Name> 
     <Desc>abcdefghigj</Desc> 
     <Type>body</Type> 
     <Snippet> 
      <![CDATA[<total>12345</total>]]> 
     </Snippet> 
    </Vector> 
</Vectors> 

I 클래스 벡터의 2 개 자바 객체를 만들려고합니다. 클래스 벡터는 ..

package com.abc.TryXmltoJava; 

    import java.util.List; 
    import javax.xml.bind.annotation.*; 

    public class Vector { 
     int Id, 
     String Name; 
     String Desc; 
     String Type; 

     @XmlElement 
     public String getName() { 
      return Name; 
     } 
     public void setName(String name) { 
      this.Name = name; 
     } 

     @XmlElement 
     public String getDesc() { 
      return Desc; 
     } 
     public void setDesc(String desc) { 
      this.Desc = desc; 
     } 

     @XmlElement 
     public String getType() { 
      return Type; 
     } 
     public void setType(String type) { 
      this.Type = type; 
     } 
} 

두 객체를 추적하고 목록 유틸리티를 사용하여 벡터 개체의 목록을 생성 이제 내가 만든 벡터 클래스 아래에 주어진 보이는

package com.abc.TryXMLtoObject; 

import javax.xml.bind.annotation.*; 

@XmlRootElement(name="Vectors") 
public class Vectors { 

@XmlElement(name="Vector") 
    Vector vector; 


    public Vector getVector() { 
     return vector; 
    } 

    public void setVector(Vector vector1) { 
     this.vector = vector1; 
    } 
} 
나는 비 직렬화하려고합니다

java 객체의리스트를 생성하는이 2 개의 클래스를 사용하는 xml 객체

javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"Vectors"). Expected elements are (none) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(Unknown Source) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Unknown Source) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Unknown Source) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Unknown Source) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(Unknown Source) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(Unknown Source) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(Unknown Source) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(Unknown Source) 
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(Unknown Source) 
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source) 
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(Unknown Source) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source) 
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) 
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) 
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) 
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source) 
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source) 
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(Unknown Source) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(Unknown Source) 
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(Unknown Source) 
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(Unknown Source) 
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(Unknown Source) 
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(Unknown Source) 
    at com.abc.TryXMLtoObject.JAXBExampleUnmarshal.main(JAXBExampleUnmarshal.java:17) 
+0

시도 네임 스페이스 – David

+0

을 추가하는 것은이 될 수 있을까 오타? (uri : "", local : "Vkectors"). "Vkectors"가 제대로 보이지 않습니다. – Luhar

+0

그래, 그건 오타 였어.하지만 여전히 같은 오류가 발생 했어. 로컬 : "벡터" – Sanket

답변

2

귀하의 예제의 다음 버전은 나를 위해 일한 :

벡터

pointed out by popfalushi으로 VectorsVector의 많은 경우에 보유 List 속성을 가져야한다.

package com.abc.TryXmltoJava; 

import java.util.List; 
import javax.xml.bind.annotation.*; 

@XmlRootElement(name="Vectors") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Vectors { 

    @XmlElement(name="Vector") 
    List<Vector> vector; 

} 

벡터

이 필드에 JAXB 주석을 지정하고자하는 경우에, 당신은 유형 수준에서 @XmlAccessorType(XmlAccessType.FIELD)을 지정해야합니다 (참조 : http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html을). 또한 기본 매핑은 @XmlElement이므로 명시 적으로 해당 주석을 추가 할 필요가 없습니다 (http://blog.bdoughan.com/2012/07/jaxb-no-annotations-required.html 참조).

package com.abc.TryXmltoJava; 

import javax.xml.bind.annotation.*; 

@XmlAccessorType(XmlAccessType.FIELD) 
public class Vector { 
    int Id; 
    String Name; 
    String Desc; 
    String Type; 
} 

JAXBExampleUnmarshal

나는 개체가 완전히 비 정렬 화 조작 중에 채워되었다는 것을 증명하기 위해, 다시 XML로 개체를 작성하는 데모 코드를 업데이트했습니다.

package com.abc.TryXmltoJava; 

import java.io.File; 
import javax.xml.bind.*; 

public class JAXBExampleUnmarshal { 

    public static void main(String[] args) { 

     try { 
      File file = new File("C:\\file.xml"); 
      JAXBContext jaxbContext = JAXBContext.newInstance(Vectors.class); 

      Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); 
      Vectors vectors = (Vectors) jaxbUnmarshaller.unmarshal(file); 
      System.out.println(vectors); 

      Marshaller marshaller = jaxbContext.createMarshaller(); 
      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
      marshaller.marshal(vectors, System.out); 

     } catch (JAXBException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

file.xml

<?xml version="1.0" encoding="UTF-8"?> 
<Vectors> 
    <Vector> 
     <Id>1</Id> 
     <Name>abc</Name> 
     <Desc>abcdefg</Desc> 
     <Type>body</Type> 
     <Snippet> 
      <![CDATA[<total>1234</total>]]> 
     </Snippet> 
    </Vector> 
    <Vector> 
     <Id>2</Id> 
     <Name>def</Name> 
     <Desc>abcdefghigj</Desc> 
     <Type>body</Type> 
     <Snippet> 
      <![CDATA[<total>12345</total>]]> 
     </Snippet> 
    </Vector> 
</Vectors> 

출력 아래

데모 코드를 실행의 출력입니다 :

[email protected] 
<?xml version="1.0" encoding="UTF-8"?> 
<Vectors> 
    <Vector> 
     <Id>1</Id> 
     <Name>abc</Name> 
     <Desc>abcdefg</Desc> 
     <Type>body</Type> 
    </Vector> 
    <Vector> 
     <Id>2</Id> 
     <Name>def</Name> 
     <Desc>abcdefghigj</Desc> 
     <Type>body</Type> 
    </Vector> 
</Vectors> 
+0

고마워요. ..btw "@XmlAccessorType (XmlAccessType.FIELD)"을 의미합니다. – Sanket

+0

@Sanket - 기본적으로 JAXB (JSR-222) 구현은 모든 공개 입력란에 대한 메타 데이터를 생성합니다. JAXB (JSR-222) 구현이 대신 필드에 메타 데이터의 기초를두기를 원하면'@XmlAccesorType (XmlAccessType.FIELD)'를 지정할 수 있습니다. 참조 : http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html –

3

먼저, Vectors에서 당신이 List<Vector> vectorList이 아닌 하나의 단일 Vector가 있어야합니다 아래로 비 정렬 화 클래스는

package com.abc.TryXMLtoObject; 

    import java.io.File; 
    import javax.xml.bind.JAXBContext; 
    import javax.xml.bind.JAXBException; 
    import javax.xml.bind.Unmarshaller; 

    public class JAXBExampleUnmarshal { 

     public static void main(String[] args) { 

     try { 

      File file = new File("C:\\file.xml"); 
      JAXBContext jaxbContext = JAXBContext.newInstance(Vectors.class); 

      Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); 
      Vectors vectors = (Vectors) jaxbUnmarshaller.unmarshal(file); 
      System.out.println(vectors); 

     } catch (JAXBException e) { 
      e.printStackTrace(); 
     } 

    } 
} 

이 코드를 실행 한 후 .. 나는 다음과 같은 오류가 얻을 ...입니다.
또한 stacktrace unexpected element (uri:"", local:"Vkectors")의 텍스트에서 x32 어딘가에 Vkectors 요소가 있다는 것을 알 수 있습니다.
마지막으로, 모든 주석을 get-methods에 두는 것이 좋습니다. 두 가지 이유가 있습니다. 하나는 내 이름이 충돌했을 때, 다른 하나는 내 메모리가 맞으면, 다른 하나는 Hibernate 또는 다른 것과 같은 프록시를 사용할 경우입니다. 필드의 주석은 사라지 겠지만 get-methods에 대한 주석은 그대로 남습니다.

+0

아 .. 네 .. 그걸 확인하고 작동 여부를 알려 줘야 해. – Sanket

+0

+1 - 이름을 피하려면 @ xmlAccessorType (XmlAccessType.FIELD)'이 클래스에 지정되어야합니다 : http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html –

+0

주석이 달린 경우 필드'field1'을'@XmlElement'로 대체하고, 메소드'getField1()'을 사용하면 이름 충돌을 얻게됩니다. 접근 자'getProperty1() {return field1;} '을 사용하여'field1'을 주석 처리 할 수는 있지만, 저에게는보기 흉한 것으로 보입니다. – popfalushi

1

오브젝트를 복원하는 대신 먼저 Java에서 오브젝트를 작성하고 JAXB를 사용하여 지속 할 수 있습니까? 그러면 XML 파일과 JAXB가 생성하는 XML 파일의 차이점을 알 수 있습니다.

1

먼저 스택 추적 이름이 Vekctors (k를 기록하십시오)이므로 오타 일 수 있습니다. 그러나 "예상 요소는 (없음)"이라고 표시됩니다. Vectors 클래스에서는 Vector 요소 만 선언 했으므로 두 요소를 Vectors 요소 안에 넣을 수 없습니다.

1

호스에 대해 설명하는이 답변을 generate classes from an xsd 번으로 볼 수 있습니다. 또한 원시 XML에서 xsd를 생성하는 자원에 대한 링크를 제공합니다.

스택 추적은 또한 "Vkectors"를 참조합니다 - 소스 파일에서 오타가 있었습니까?

마지막으로 jaxb tutorial으로 시작하여 거기에서 일할 수 있습니다.

행운을 빈다.

관련 문제