2013-05-20 75 views
2

我想使用JAXB將XML文件解組爲java對象。 XML文件非常大,並且包含一些節點,在某些情況下,爲了提高性能,我想跳過這些節點,因爲這些元素不可由客戶端Java程序編輯。使用JAXB部分解組XML以跳過某些xmlElement

的樣本XML如下:

<Example id="10" date="1970-01-01" version="1.0"> 
    <Properties>...</Properties> 
    <Summary>...</Summary> 
    <RawData> 
     <Document id="1">...</Document> 
     <Document id="2">...</Document> 
     <Document id="3">...</Document> 
     ------ 
     ------ 
    </RawData> 
    <Location></Location> 
    <Title></Title> 
    ----- // more elements 
</Example> 

我有兩個用例:

  • 解組到實施例對象包含屬性,摘要,RAWDATA等不跳過任何RAWDATA。 (已經完成了這部分)
  • 解組到排除RawData的Example對象。嵌套在RawData中的元素非常大,所以不希望在此用例中閱讀此內容。

現在我想解組XML,使RawData可以跳過。我嘗試過在this link提供的技術。

使用上述鏈接提供的技術還會跳過RawData之後的所有元素。

+0

可以用streamFilter來跳過元素嗎? – Pratham

回答

2

我有固定的XMLEventReader問題與下面的代碼:

public class PartialXmlEventReader implements XMLEventReader { 

private final XMLEventReader reader; 
private final QName qName; 
private boolean skip = false; 

public PartialXmlEventReader(final XMLEventReader reader, final QName element) { 
    this.reader = reader; 
    this.qName = element; 
} 

@Override 
public String getElementText() throws XMLStreamException { 
    return reader.getElementText(); 
} 

@Override 
public Object getProperty(final String name) throws IllegalArgumentException { 
    return reader.getProperty(name); 
} 

@Override 
public boolean hasNext() { 
    return reader.hasNext(); 
} 

@Override 
public XMLEvent nextEvent() throws XMLStreamException { 
    while (isEof(reader.peek())) { 
     reader.nextEvent(); 
    } 

    return reader.nextEvent(); 
} 

@Override 
public XMLEvent nextTag() throws XMLStreamException { 
    return reader.nextTag(); 
} 

@Override 
public XMLEvent peek() throws XMLStreamException { 
    return reader.peek(); 
} 

@Override 
public Object next() { 
    return reader.next(); 
} 

@Override 
public void remove() { 
    reader.remove(); 
} 

@Override 
public void close() throws XMLStreamException { 
    reader.close(); 
} 

private boolean isEof(final XMLEvent e) { 
    boolean returnValue = skip; 
    switch (e.getEventType()) { 
    case XMLStreamConstants.START_ELEMENT: 
     final StartElement se = (StartElement) e; 
     if (se.getName().equals(qName)) { 
      skip = true; 
      returnValue = true; 
     } 
     break; 
    case XMLStreamConstants.END_ELEMENT: 
     final EndElement ee = (EndElement) e; 
     if (ee.getName().equals(qName)) { 
      skip = false; 
     } 
     break; 
    } 
    return returnValue; 
} 

}

在解只是通過這個eventReader的解組方法

final JAXBContext context = JAXBContext.newInstance(classes); 
    final Unmarshaller um = context.createUnmarshaller(); 
    Reader reader = null; 
    try { 
     reader = new BufferedReader(new FileReader(xmlFile)); 
     final QName qName = new QName("RawData"); 
     final XMLInputFactory xif = XMLInputFactory.newInstance(); 
     final XMLEventReader xmlEventReader = xif.createXMLEventReader(reader); 
     final Example example = 
       (Example) um.unmarshal(new PartialXmlEventReader(xmlEventReader, qName)); 
     } 
    } finally { 
     IOUtils.closeQuietly(reader); 
    } 
1

我希望這將有助於

try { 
     // First create a new XMLInputFactory 
     XMLInputFactory inputFactory = XMLInputFactory.newInstance(); 
     // Setup a new eventReader 
     InputStream in = new FileInputStream("myXml"); 
     XMLEventReader eventReader = inputFactory.createXMLEventReader(in); 
     // Read the XML document 
     Example example = null; 

     while (eventReader.hasNext()) { 
      XMLEvent event = eventReader.nextEvent(); 

      if (event.isStartElement()) { 
       StartElement startElement = event.asStartElement(); 
       // If we have a example element we create a new example 
       if (startElement.getName().getLocalPart().equals("Example")) { 
        example = new Example(); 
        // We read the attributes from this tag and add the date 
        // and id attribute to our object 
        Iterator<Attribute> attributes = startElement 
          .getAttributes(); 
        while (attributes.hasNext()) { 
         Attribute attribute = attributes.next(); 
         if (attribute.getName().toString().equals("date")) { 
          example.setDate(attribute.getValue()); 
         } else if (attribute.getName().toString().equals("id")) { 
          example.setId(attribute.getValue()); 
         } 

        } 
       } 

       //get the Properties tag and add to object example 
       if (event.isStartElement()) { 
        if (event.asStartElement().getName().getLocalPart() 
          .equals("Properties")) { 
         event = eventReader.nextEvent(); 
         example.setProperites(event.asCharacters().getData()); 
         continue; 
        } 
       } 
       //get the Summary tag and add to object example 
       if (event.asStartElement().getName().getLocalPart() 
         .equals("Summary")) { 
        event = eventReader.nextEvent(); 
        example.setSummary(event.asCharacters().getData()); 
        continue; 
       } 

       // when you encounter the Rawdata tag just continue 
       //without adding it to the object created 
       if (event.asStartElement().getName().getLocalPart() 
         .equals("Rawdata")) { 
        event = eventReader.nextEvent(); 
        // don't do anything 
        continue; 
       } 

       //get the location tag and add to object example 
       if (event.asStartElement().getName().getLocalPart() 
         .equals("Location")) { 
        event = eventReader.nextEvent(); 
        example.setLocation(event.asCharacters().getData()); 
        continue; 
       } 
       // read and add other elements that can be added 
      } 
      // If we reach the end of an example element/tag i.e closing tag 
      if (event.isEndElement()) { 
       EndElement endElement = event.asEndElement(); 
       if (endElement.getName().getLocalPart().equals("Example")) { 
        //do something 
       } 
      } 

     } 
    } catch (FileNotFoundException | XMLStreamException e) { 
    } 
+0

我試圖添加更多評論 – Ayodeji

+1

我不想迭代xml來單獨創建每個對象,因爲我的對象非常複雜。所以我們使用jaxb進行自動綁定。 – Pratham