2012-08-29 56 views
4

我想解组一个大的xml文档的中间元素。目前使用JAXB和Woodstox。使用jaxb解组xml文档的中间部分

,我需要和解组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的所有值。它被显示为空。

下面是代码:

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>嵌套从根5-6的水平上面的代码仅工作。如果在<Values>之前存在15个标签,则此代码不起作用。与仅仅使用JAXB和解组所有元素相比,它的速度相对较慢,但这需要我为永远不会使用的数据创建对象。

所以,我的问题是 - 有无论如何提高性能? 为什么它不能在xml深处嵌套? 如何从Person属性获取ID值?

回答

6

以下应该有所帮助:


为什么不是工作时,它在XML嵌套深?

如果不工作,你的意思是抛出类似的异常:

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) 

的,你可以改变前进XmlStreamReader的代码:

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

无论如何增加表现?

StAX是一种解析XML文档的非常快速的方法。无论如何,它可能正在被JAXB实现使用。字符串比较可能会很慢。 由于您正在使用Woodstox及其实习生元素名称(请参阅:第6.1节“字符串实习:http://woodstox.codehaus.org/FAQ”)。你可以对字符串进行身份检查,而不是使用equals方法。

 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属性值?

默认情况下,XML的JAXB(JSR-222),实现将您ID字段映射到一个属性,叫做id而不是ID。您可以覆盖此默认设置如下:

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

是的,这确实有助于提高我的表现。但是我还有一个问题,是否还有其他可用的类/方法,以便我不使用文件读取,而是将XML数据作为字符串传递给JAXB/Stax。 – Ikshvak

+0

@Ikshvak - 你可以在StringReader的一个实例中包装一个XML String,并从中解组。 JAXB支持许多不同类型的解组。 –