Stax XMLStreamReader 检查下一个事件而不前进

问题描述

我有一个包含许多事件的大 XML 文件。我想unmarshal他们。由于它是一个文件,我想一个一个unmarshal 它们,这样整个文件就不会存储在内存中。它对某些事件有效,但对某些事件无效,因为它无法映射到特定类,因为它已经在下一个事件中。

注意:我知道 XMLEventReader 但他们中的大多数人都提到它的内存效率不是很高,所以我尝试使用 XMLStreamReader 并完成此操作。

以下是包含事件的示例 XML 文件

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<extension>
    <extension>
        <c>
            <name>CName</name>
            <age>CAge</age>
        </c>
    </extension>
</extension>
<extension>
    <b>
        <name>BName</name>
        <age>BAge</age>
    </b>
</extension>
<a>
    <name>AName</name>
    <age>AAge</age>
</a>
<extension>
    <b>
        <name>BName</name>
        <age>BAge</age>
    </b>
</extension>

我有 3 个与它们对应的类,它们将用于 unmarshalling

@XmlRootElement(name = "a")
@XmlAccessorType(XmlAccesstype.FIELD)
@XmlType(name = "a",propOrder = {"name","age"})
public class A
{
    private String name;
    private String age;
    //Getter,Setter and other constructors
}

@XmlRootElement(name = "extension")
@XmlAccessorType(XmlAccesstype.FIELD)
@XmlType(name = "extension","age"})
public class B
{
    @XmlPath("b/name/text()")
    private String name;
    @XmlPath("b/age/text()")
    private String age;
    //Getter,"age"})
public class C
{
    @XmlPath("extension/c/name/text()")
    private String name;
    @XmlPath("extension/c/age/text()")
    private String age;
    //Getter,Setter and other constructors
}

以下是我将用于 Mainunmarshalling 类:

public class Main{
     
    private Unmarshaller unmarshaller = null;
    private JAXBContext jaxbContext = null;
  
    public void unmarshaller(InputStream xmlStream) throws IOException,XMLStreamException,JAXBException {
        final XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
        final XMLStreamReader streamReader = xmlInputFactory.createXMLStreamReader(xmlStream);
        
        //Navigate to next and start of the XML Elements
        streamReader.next();

        //Read Until the end of the file
        while (streamReader.hasNext()) {
            //Check if the element is "extension" if so its Class B or C
            if (streamReader.isstartElement() && streamReader.getLocalName().equalsIgnoreCase("extension")) {

                //Check if the next element also has "extension" if so its Class C
               //This is IMPORTANT step for mapping b/w Class B & C which is confusing me
                streamReader.next();

                if (streamReader.isstartElement() && streamReader.getLocalName().equalsIgnoreCase("extension")) {
                    //If there is 2 extension tag then its Class C
                    classspecifier(C.class);
                    final C cInfo = unmarshaller.unmarshal(streamReader,C.class).getValue();
                    System.out.println(cInfo);
                }else{
                    //If there is no "extension" tag then its Class B
                    //THIS IS WHERE ITS FAILING: IF ITS NOT CLASS C THEN IT WOULD COME HERE BUT SINCE I HAVE 
                    //ALREADY MOVED TO NEXT ELEMENT TO CHECK IF ITS "extension" ITS UNABLE TO MAP THE WHOLE CLASS TO CLASS B
                    classspecifier(B.class);
                    final B bInfo = unmarshaller.unmarshal(streamReader,B.class).getValue();
                    System.out.println(bInfo);
                }
            }else if(streamReader.isstartElement() && streamReader.getLocalName().equalsIgnoreCase("a")){
                //If there is no "extension" then its class A
                classspecifier(A.class);
                final A aInfo = unmarshaller.unmarshal(streamReader,A.class).getValue();
                System.out.println(aInfo);
            }
        }
    }
    
    //Method to initialize the JAXBContext and Unmarshaller based on the incoming eventType
    private void classspecifier(Class eventTypeClass) throws JAXBException {
        this.jaxbContext = JAXBContext.newInstance(eventTypeClass);
        unmarshaller = jaxbContext.createUnmarshaller();
    }
    
    public static void main(String args[]){
        try{
            InputStream xmlStream = Main.class.getClassLoader().getResourceAsstream("InputEPCISEvents.xml");
            unmarshaller(xmlStream);
        } catch (Exception e) {
            System.out.println(e);
            e.printstacktrace();
        }
    }
}

我面临的问题是区分 BC 类。

  1. 我需要检查传入的 localName 是否为 extension
  2. 如果是 extension,那么我需要检查下一个元素 localName 是否也是 extension
  3. 如果是,则为 class C,否则为 class B
  4. 因为在 Step-2 中,我已经移至 streamreader.next(),如果元素不是 extension,则无法将其映射到 class B,因为我已移至 { {1}} 元素,它没有整个类。

我正在寻找一些可以执行以下操作的解决方案:

  1. 如果第二次验证中的元素不是 next(),则返回前一个元素,然后将整个类分配给 extension
  2. 在进行检查时将 class B 分配给 streamReader,以便您在 tempreader 中前进。但这也失败了。

有没有办法回到流中的前一个元素,否则我该如何解决这个问题?我希望我能够提供一个完整的解释。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...