用Java解析以下格式的xml文件

用Java解析以下格式的xml文件,java,xml,parsing,xml-parsing,Java,Xml,Parsing,Xml Parsing,我有一个以下格式的xml文件,作为服务的响应。它不是传统的xml格式,其中值包含在各自的标记中。这只是一个示例,而实际文件将包含数百个元素。如何以最有效的方式到达所需的节点(比如“TDE-2”),并将其值放入映射中,如{map(TenderID,TDE-2),map(ContactID,null)} 柔嫩的 联系人ID 地址 描述 日期 TDE-1 标书1 09/30/2016 TDE-2 投标书2 10/02/2016 JAXB允许您将XML反序列化为Java对象。如果创建JavaPOJO以

我有一个以下格式的xml文件,作为服务的响应。它不是传统的xml格式,其中值包含在各自的标记中。这只是一个示例,而实际文件将包含数百个元素。如何以最有效的方式到达所需的节点(比如“TDE-2”),并将其值放入映射中,如
{map(TenderID,TDE-2),map(ContactID,null)}


柔嫩的
联系人ID
地址
描述
日期
TDE-1
标书1
09/30/2016
TDE-2
投标书2
10/02/2016

JAXB允许您将XML反序列化为Java对象。如果创建JavaPOJO以匹配XML文档模型,那么可以使用JAXB在POJO中解组XML

例如:

POJO:

Report.java

import java.util.List;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Report {

    private List<ReportRow> reportRows;

    public List<ReportRow> getReportRows() {
        return reportRows;
    }

    @XmlElement(name = "report_row")
    public void setReportRows(List<ReportRow> reportRows) {
        this.reportRows = reportRows;
    }
}
}

读取XML并将其绑定到java对象的代码:

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import org.junit.Test;

public class JaxbTest {

    @Test
    public void testFoo() throws JAXBException {

        File xmlFile = new File("src/test/resources/reports.xml");
        JAXBContext context = JAXBContext.newInstance(Report.class, ReportRow.class);
        Unmarshaller jaxbUnmarshaller = context.createUnmarshaller();
        Report report = (Report) jaxbUnmarshaller.unmarshal(xmlFile);
        ReportRow reportYouWant = report.getReportRows().stream().filter(reportRow -> reportRow.getC1().equals("TDE-1"))
                .findFirst().get();

    }
}
您还需要将以下依赖项添加到构建脚本中:

compile group: 'javax.xml', name: 'jaxb-impl', version: '2.1'
compile group: 'javax.xml', name: 'jaxb-api', version: '2.1'

“区别”到底是什么“您在对答案的评论中所说的是什么?它是简单的XML,只需要解析,不是吗?您能澄清确切的问题是什么吗?使用SAX或StaX解析XML。在读取标题时,您可以存储列描述。稍后,在每行上,您可以使用列描述到列的关系来标识t他写了一些有趣的专栏。但不要指望我们为您编写整个代码。如果您遇到困难,您应该自己动手,并向我们展示您的代码。@vanje我已经按照您的建议编写了代码;但是,如果我感兴趣的数据位于最后一个元素中,我将按顺序遍历xml文件,直到xml文件的结尾。我正在寻找一段代码建议优化我的代码,而不是原始代码。如果您想更快地访问每个密钥,您有几种可能性(但所有这些都需要至少解析一次整个XML文档)1.如果您的内存足够大,您可以创建一个哈希映射,然后使用该映射访问数据。2.将数据放入数据库表并创建适当的索引。您的数据结构非常适合普通关系数据库。3.使用eXist或BaseX之类的XML数据库。但我不建议将其用于您的数据,因为它是基本上是一个没有层次结构的平面表。第四种选择:4.手动创建自己的索引。解析XML文件,并在索引哈希映射中存储每个元素的文件位置以及键列的值。只有当键数据对于主存来说不是太大,但它需要的空间小于容纳所有数据时,这种方法才有效内存中。然后使用映射查找密钥的文件位置,然后使用随机访问文件从文件中仅读取该元素。但这是一项大量工作。我会使用数据库表,可能与H2或Apache Derby之类的嵌入式数据库系统一起使用。我收到一个错误,即“找不到适合解组的方法”当我创建一个ReportCollection类的对象时。你能指导我吗?我已经更新了答案中的示例。我已经测试了这段代码,它是有效的。如果你对它满意,请接受它作为答案。
import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import org.junit.Test;

public class JaxbTest {

    @Test
    public void testFoo() throws JAXBException {

        File xmlFile = new File("src/test/resources/reports.xml");
        JAXBContext context = JAXBContext.newInstance(Report.class, ReportRow.class);
        Unmarshaller jaxbUnmarshaller = context.createUnmarshaller();
        Report report = (Report) jaxbUnmarshaller.unmarshal(xmlFile);
        ReportRow reportYouWant = report.getReportRows().stream().filter(reportRow -> reportRow.getC1().equals("TDE-1"))
                .findFirst().get();

    }
}
compile group: 'javax.xml', name: 'jaxb-impl', version: '2.1'
compile group: 'javax.xml', name: 'jaxb-api', version: '2.1'