2012-08-29 3 views
4

큰 XML 문서의 가운데 요소를 언 마샬하려고합니다. 현재 JAXB와 Woodstox를 사용 중입니다. 나는 비 직렬화 할 필요가 XML 중간 요소의jaxb를 사용하여 xml 문서의 가운데 정렬 해제

예 : 내가 사용하는

<Values> 
    <Person ID="ABC"> 
    <FirstName>Shawn</FirstName> 
    <LastName>Mark</LastName> 
    <Age>3</Age> 
    </Person> 
    <Person ID="DEF"> 
     <FirstName>John</FirstName> 
     <LastName>Durell</LastName> 
     <Age>4</Age> 
    </Person> 
</Values> 

, JAXB 프로 클래스는 다음과 같습니다

@XmlRootElement(name = "Values") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Attributes 
{ 
    @XmlElement(name = "Person") 
    private ArrayList<Person> persons; 

    public ArrayList<Person> getPersons() 
    { 
     return persons; 
    } 
} 


@XmlAccessorType(XmlAccessType.FIELD) 
public class Person 
{ 
    @XmlAttribute 
    private String ID; 

    @XmlElement(name = "FirstName") 
    private String firstName; 

    @XmlElement(name = "LastName") 
    private String lastName; 

    @XmlElement(name = "Age") 
    private String age; 
} 

나는 ID를 제외한 모든 값을 비 직렬화 할 수 있어요. 그것은 null로 표시됩니다. <Values>이 루트 5-6 레벨을 중첩 할 때 위의 코드는 작동하고

final XMLInputFactory xif = XMLInputFactory.newInstance(); 
final StreamSource xml = new StreamSource(pathToxmlFile); 
XMLStreamReader xsr; 
xsr = xif.createXMLStreamReader(xml); 
xsr.nextTag(); 
while (!xsr.getLocalName().equals("Values")) 
{ 
    xsr.nextTag(); 
} 

final JAXBContext jc = JAXBContext.newInstance(Attributes.class); 
final Unmarshaller unmarshaller = jc.createUnmarshaller(); 
final JAXBElement<Attributes> jb = unmarshaller.unmarshal(xsr, Attributes.class); 

: 여기

는 코드입니다. <Values> 앞에 15 개의 태그가있는 경우이 코드는 작동하지 않습니다.

또한 JAXB를 사용하고 모든 요소를 ​​비 정렬 화하는 것과 비교할 때 상대적으로 매우 느리지 만 절대 사용되지 않는 데이터 용 개체를 만들어야합니다.

내 질문은 - 어쨌든 성능을 향상시킬 수 있습니까? xml에 중첩 된 경우 왜 작동하지 않습니까? Person 속성에서 ID 값을 가져 오는 방법은 무엇입니까?

답변

6

다음은 도움이 될 것입니다


이유는 XML의 경우 중첩 된 깊이 작동하지 않을 것입니다?

만약 당신이 같은 예외를 던지는 의미 작동하지 의하여 :

while(xsr.hasNext()) { 
     if(xsr.isStartElement() && xsr.getLocalName().equals("Values")) { 
      break; 
     } 
     xsr.next(); 
    } 

: 당신이 XmlStreamReader에 전진 코드를 변경할 수

Exception in thread "main" javax.xml.stream.XMLStreamException: ParseError at [row,col]:[4,13] 
Message: found: CHARACTERS, expected START_ELEMENT or END_ELEMENT 
    at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.nextTag(XMLStreamReaderImpl.java:1247) 
    at blog.stax.middle.UnmarshalDemo.main(UnmarshalDemo.java:15) 

어쨌든 성능을 향상시킬 수 있습니까?

StAX는 XML 문서를 매우 빠르게 구문 분석합니다. JAXB 구현에서 어쨌든 사용되고있을 것입니다. 문자열 비교가 느려질 수 있습니다. Woodstox를 사용하고 있으며 요소 이름을 인턴하기 때문에 (6.1 문자열 인 그레이킹 : http://woodstox.codehaus.org/FAQ 참조). equals 메서드 대신에 문자열에 대한 ID 검사를 수행 할 수 있습니다.

 if(Boolean.TRUE.equals(xsr.getProperty("org.codehaus.stax2.internNames"))) { 
     while(xsr.hasNext()) { 
      if(xsr.isStartElement() && xsr.getLocalName() == "return") { 
       break; 
      } 
      xsr.next(); 
     } 
    } else { 
     while(xsr.hasNext()) { 
      if(xsr.isStartElement() && xsr.getLocalName().equals("return")) { 
       break; 
      } 
      xsr.next(); 
     } 
    } 

어떻게 사람의 ID 값 속성을 얻는 방법?기본 속성에 ID 필드를 매핑 할 것이다 JAXB (JSR-222) 구현이 id하지 ID라는 XML으로

. 이 기본값을 다음과 같이 재정의 할 수 있습니다.

@XmlAttribute(name="ID") 
private String ID; 
+1

예 이렇게하면 성능이 향상되었습니다. 하지만 한 가지 더 질문이 있습니다. JAXB/Stax에 String으로 XML 데이터를 전달하는 파일에서 읽는 대신 오히려 사용할 수있는 다른 클래스/메서드를 사용할 수 있습니까? – Ikshvak

+0

@Ikshvak -'StringReader' 인스턴스에서 XML'String'을 래핑하고 그로부터 비 정렬화할 수 있습니다. JAXB는 비 정렬화할 여러 가지 유형을 지원합니다. –

관련 문제