XML Splitter
El XML Splitter proporcionado por IPF está implementado usando la biblioteca akka-stream-alpakka-xml. Toma una component hierarchy que define la estructura de los elementos XML a dividir.
Cabe señalar que los datos de los elementos XML generados estarán compactados. Es decir, cualquier espacio en blanco extra en el documento original se eliminará de los componentes publicados. Las versiones futuras pueden incluir configuración para preservar el formato de origen.
Maven Dependency
Para usar el XML splitter, se debe proporcionar la siguiente dependencia, con una versión que coincida con ipf-debulker-core para asegurar la compatibilidad.
<dependency>
<groupId>com.iconsolutions.ipf.debulk</groupId>
<artifactId>ipf-debulker-xml-splitter</artifactId>
<version>${ipf-debulker-core.version}</version>
</dependency>
Ejemplo de uso
Imagina que queremos procesar archivos XML potencialmente grandes que contienen datos sobre libros en una biblioteca y dividirlo en partes más pequeñas, para que puedan ser usados por algún sistema downstream.
El archivo de ejemplo es pequeño con fines de demostración, pero podría contener un gran número de elementos de libros.
example.xml
<library>
<name>Library of Alexandria</name>
<book>
<author>Martin, Robert</author>
<title>Clean Code</title>
<chapter>
<name>Clean Code</name>
<startPage>1</startPage>
</chapter>
<chapter>
<name>Meaningful Names</name>
<startPage>17</startPage>
</chapter>
</book>
<book>
<author>Bloch, Joshua</author>
<title>Effective Java</title>
<chapter>
<name>Introduction</name>
<startPage>1</startPage>
</chapter>
<chapter>
<name>Creating and Destroying Objects</name>
<startPage>5</startPage>
</chapter>
</book>
</library>
Dado nuestro XML de ejemplo, podríamos decidir dividirlo usando la siguiente jerarquía.
library
└── book
└── chapter
Nota: la ruta al componente hijo debe ser relativa respecto del padre en la jerarquía; en el ejemplo anterior esperamos que el elemento book sea hijo directo del elemento library. Si no es el caso, debemos especificar la ruta relativa delimitada con ..
Con estos prerrequisitos fuera del camino, escribamos el programa. Ten en cuenta que este ejemplo usa Project Reactor para convertir Flow.Publisher de Java 9 a un Flux para facilitar la suscripción a los datos, pero podría reemplazarse por otra biblioteca reactiva compatible con las bibliotecas reactivas de Java 9, por ejemplo RxJava.
ActorSystem system = ActorSystem.create();
Splitter splitter = new AkkaXmlSplitter(system);
InputStream stream = getClass().getClassLoader().getResourceAsStream("example.xml");
ComponentHierarchy root = ComponentHierarchy.root("library");
ComponentHierarchy book = root.addChild("book");
book.addChild("chapter");
Flow.Publisher<DebulkComponent> publisher = splitter.split(stream, root);
Flux<DebulkComponent> flux = JdkFlowAdapter.flowPublisherToFlux(publisher);
List<DebulkComponent> components = flux.collectList().block();
components.forEach(System.out::println);
Al ejecutar este código debería imprimirse en la consola una serie de componentes extraídos.
output
DebulkComponent(bulkId=null, id=2318c220-515d-4904-a71f-daf1bc2f7b1a, parentId=f625f075-a1d3-4865-b0f3-c83aa1f485c6, marker=library.book.chapter, index=2, content=<chapter><name>Clean Code</name><startPage>1</startPage></chapter>)
DebulkComponent(bulkId=null, id=4bd76b08-6dcb-4f09-882e-f20233ed375d, parentId=f625f075-a1d3-4865-b0f3-c83aa1f485c6, marker=library.book.chapter, index=3, content=<chapter><name>Meaningful Names</name><startPage>17</startPage></chapter>)
DebulkComponent(bulkId=null, id=f625f075-a1d3-4865-b0f3-c83aa1f485c6, parentId=65fdf7ee-9646-4ba2-a654-78fab7d4be43, marker=library.book, index=1, content=<book><author>Martin, Robert</author><title>Clean Code</title></book>)
DebulkComponent(bulkId=null, id=9fbf87f5-8873-4512-8c53-29488fd0e0e0, parentId=b763d8e5-880f-43f3-90f2-430eeb33218d, marker=library.book.chapter, index=5, content=<chapter><name>Introduction</name><startPage>1</startPage></chapter>)
DebulkComponent(bulkId=null, id=c28d4e18-0610-41b0-bb0a-5f85723788af, parentId=b763d8e5-880f-43f3-90f2-430eeb33218d, marker=library.book.chapter, index=6, content=<chapter><name>Creating and Destroying Objects</name><startPage>5</startPage></chapter>)
DebulkComponent(bulkId=null, id=b763d8e5-880f-43f3-90f2-430eeb33218d, parentId=65fdf7ee-9646-4ba2-a654-78fab7d4be43, marker=library.book, index=4, content=<book><author>Bloch, Joshua</author><title>Effective Java</title></book>)
DebulkComponent(bulkId=null, id=65fdf7ee-9646-4ba2-a654-78fab7d4be43, parentId=, marker=library, index=0, content=<library><name>Library of Alexandria</name></library>)