Tips: Use Stax to merge XML documentation

xiaoxiao2021-03-06  71

The new XML document derived from the input document is one of the flash points of Streaming API for XML (Stax). This technique explores how the client application effectively combines two input XML documents using an event-based API.

In the previous skill, "Write XML Documents using Stax", I explain how to use the underlying pointer-based STAX API to create an XML document by programming. In this trick, I use the high-level event-based API demonstrate how to create a program and combine two input XML documents into one.

At the same time, multiple XML documents may be handled a big challenge. For example, the SAX parser submits the parsing event by callback customer application. Because the SAX parser controls this process, the client application does not have the opportunity to synchronize different input sources. Therefore, the programmer often helps the DOM parser when you need to handle multiple documents. However, the cost is additional resource occupation - the node tree of all input documents must have resident in memory.

Stax does not exist this defect. As its name is indicated, its goal is to combine flow applications such as two documents. The following example illustrates how this function is implemented. Suppose you need to merge two documents that contain the product list. Each document has a element, which contains one or more elements, sorted in alphabetical order based on the PID attribute. Listing 1 is an example of such a document:

Listing 1. Product list

In Listing 2, I use the traditional merge algorithm to merge a list from two documents. By comparing the consolidation conditions from the two documents, you decide to copy an event to the output document from the document 1 or document 2. This work is completed by the ReadtOndExTelement () method. This method has some other logic for checking the end of the product list. Documentation starts and document ends need to be handled.

Listing 2. Merge document

Import java.io. *; import javax.xml.namespace.qname; import javax.xml.stream. *; import javax.xml.stream.events.xmlevent;

Public class merger {

Private static final qname prodname = new qname ("product"); private static factory qname pidname = new qname ("pid");

public static void main (String [] args) throws FileNotFoundException, XMLStreamException {// Use the reference implementation for the XML input factory System.setProperty ( "javax.xml.stream.XMLInputFactory", "com.bea.xml.stream.MXParserFactory "); // Create the XML input factory XMLInputFactory factory = XMLInputFactory.newInstance (); // Create XML event reader 1 XMLEventReader r1 = factory.createXMLEventReader (new FileReader (" prodList1.xml ")); // Create XML event reader 2 XMLEventReader r2 = factory.createXMLEventReader (new FileReader ( "prodList2.xml")); // Create the output factory XMLOutputFactory xmlof = XMLOutputFactory.newInstance (); // Create XML event writer XMLEventWriter xmlw = xmlof.createXMLEventWriter (System.out );

// Read to first element in document 1 // and output to result document String pid1 = readToNextElement (r1, xmlw, false); // Read to first element in document 1 // without writing to result document String pid2 = readtonExTelement (R2, Null, False); // Loop over Both XML Input Streams While (PID1! = NULL || PID2! = Null) {// compare merge criteria if (PID2 == Null || (PID1! = NULL && PID1.COMPARETO (PID2) <= 0)) // Continue in Document 1 PID1 = ReadtoneXTelement (R1, XMLW, PID2 == NULL); Else // Continue In Document 2 PID2 = ReadtoneXtelement (R2, XMLW, PID1 == null);} XMLW.Close ();

/ ** * @param reader - the document reader * @param writer - the document writer * @param processEnd - forces the document end to be written * @return - the next merge criterion value * @throws XMLStreamException * / private static String readToNextElement (XMLEventReader reader, XMLEventWriter writer, boolean processEnd) throws XMLStreamException {// Nesting level int level = 0; while (true) {// Read event to be written to result document XMLEvent event = reader.next (); // Avoid double Processing of document end if (! processend) Switch (event.geteventType ()) {copy xmlevent.start_element: level; break; case xmlevent.end_element: if (--level <0) Return Null; Break;} // Output Event if (Writer! = NULL) Writer.Add (Event); // Look At Next E VENT Event = Reader.peek (); Switch (Event.geteventType ()) {case xmlevent.start_element: // start element - stop at Element qname name = event.asstartElement (). getname (); if (Name . Equals ()) {return Event .asstartElement () .GetaTributebyName (pidname) .GetValue ();} Break; case xmlevent.end_document: // stop at end of document return null;}}}}

As you can see, an event-based API is very suitable for derived documents from other documents. If you use the bottom-based pointer-based API, you also need to call different ways to call different methods, and use event-based APIs, just transfer normal events to the ADD () method of the event writer. Conclusion This technique demonstrates an event-based API based on the Piping XML application, such as the merge of documentation. On November 3, 2003, Stax passed Final JSR-0173 Approval Ballot. It will add some useful things to each Java programmer's toolbox.

转载请注明原文地址:https://www.9cbs.com/read-92373.html

New Post(0)