簡體   English   中英

使用jaxb解組xml文檔的中間部分

[英]Unmarshalling the middle of xml document using jaxb

我試圖解組一個大的xml文檔的中間元素。 目前正在使用JAXB和Woodstox。

我需要解組的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。

這是代碼:

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

以下應該有所幫助:


當它嵌套在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();
        }
    }

如何從Person屬性中獲取ID值?

默認情況下,您的JAXB(JSR-222)實現的XML將您的ID字段映射到名為id而不是ID的屬性。 您可以按如下方式覆蓋此默認值:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM