Jesus Paradinas
Jesus Paradinas

Reputation: 187

Search through XMLs with Java 8

I need to create a tool in java 8 to search through a list of .xml files that are all in the same folder. Each file contains information of this type:

<id>135719887</id>
<FactValue>
    <name>FACT.DOCUMENT.TOTAL_DUE_AMOUNT</name>
    <valueString>832.15</valueString>
</FactValue>
<FactValue>
    <name>FACT.DOCUMENT.AUTO_PAY</name>
    <valueString>false</valueString>
</FactValue>
<FactValue>
     <name>FACT.DOCUMENT.CREDIT_CARD_EXPIRED</name>
    <valueString>false</valueString>
</FactValue>
<FactValue>
    <name>FACT.DOCUMENT.HAS_SEDONA_CHARGES</name>
    <valueString>true</valueString>
</FactValue> 

what required is a tool which can extract from a single or multiple search/query, the FACT code and its value in the following way:

id           type                   value
----------   --------------------   -------
135719887    TOTAL_DUE_AMOUNT       832.15
135719887    AUTO_PAY               false
135719887    CREDIT_CARD_EXPIRED    false
135719887    HAS_SEDONA_CHARGES     true

The queries would be, for instance:

Which Ids have the CREDIT_CARD_EXPIRED = false, AND, AUTO_PAY = true Which Ids have the CREDIT_CARD_EXPIRED = true, OR, AUTO_PAY = false What is the value of TOTAL_DUE_AMOUNT fact of the Id xxxxxxxxx

I am interested in a couple of things: 1- What data structure to use 2- How to iterate all the files

Performance is not as importat as flexibility.

Thanks in advance

Upvotes: 1

Views: 85

Answers (1)

Adrian
Adrian

Reputation: 3134

Let's suppose that FooDto is the POJO class for your XML content, then you can do something like:

public static void main(String[] args) throws Exception {
    JAXBContext jaxbContext = JAXBContext.newInstance(FooDto.class);

    Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
    FooDto fooDto1 = (FooDto) jaxbUnmarshaller.unmarshal(getInput("/Foo1.xml"));
    FooDto fooDto2 = (FooDto) jaxbUnmarshaller.unmarshal(getInput("/Foo2.xml"));

    List<String> ids = Stream.of(fooDto1, fooDto2)
            .filter(Main::creditCardIsNotExpired)
            .map(FooDto::getId)
            .collect(Collectors.toList());
}

private static boolean creditCardIsNotExpired(FooDto foo) {
    return Arrays.stream(foo.getFactValue())
            .anyMatch(fact -> fact.getName().equals("FACT.DOCUMENT.CREDIT_CARD_EXPIRED") 
                    && fact.getValueString().equals("false"));
}

This example gives you all ids for CREDIT_CARD_EXPIRED == false.

  1. Use a DTO, which can be generated from the XML using IDE plugins or other tools.
  2. Read files in a loop and create a collection of DTOs then apply your filters.

Upvotes: 2

Related Questions