使用Saxon S9API序列化DOM文档到输出流的惯用方法是什么?
Your existing code does work perfectly well for serializing a DOM document to an output stream, but we can refine it to align more closely with S9API's intended conventions and add flexibility for common serialization needs. Let's walk through the improved approach:
Key Improvements & Best Practices
- Reuse
DocumentBuilderinstances: Creating a newDocumentBuilderevery time is unnecessary and inefficient, especially if you're processing multiple documents. Initialize it once with any needed configuration (like entity resolution or validation) and reuse it. - Explicitly configure Serializer properties: Instead of relying on default settings, use S9API's built-in methods to set output options like indentation, encoding, XML version, or DOCTYPE declarations. This makes your serialization behavior explicit and consistent.
- Clean resource handling: While the JVM typically manages streams, if you're creating the output stream within your code, ensure it's closed properly (though if
outis passed in, leave closure to the caller).
Refactored Code Example
// Initialize processor once (reuse across your application if possible) Processor processor = new Processor(false); // Reusable DocumentBuilder (configure once with any needed settings) DocumentBuilder docBuilder = processor.newDocumentBuilder(); // Optional: Configure builder settings, e.g., disable validation // docBuilder.setSchemaValidationMode(SchemaValidationMode.NONE); // Convert DOM Document to XdmNode (required for S9API serialization) XdmNode sourceNode = docBuilder.build(new DOMSource(doc)); // Create and configure Serializer Serializer serializer = processor.newSerializer(out); // Set common serialization options explicitly serializer.setOutputProperty(Serializer.Property.METHOD, "xml"); serializer.setOutputProperty(Serializer.Property.INDENT, "yes"); serializer.setOutputProperty(Serializer.Property.ENCODING, "UTF-8"); serializer.setOutputProperty(Serializer.Property.OMIT_XML_DECLARATION, "no"); // Serialize the node serializer.serializeNode(sourceNode);
Why This Is More Idiomatic
Your original code skips explicit configuration of the Serializer, which means you're relying on Saxon's default behavior. While that's fine for simple cases, explicitly setting properties makes your code self-documenting and avoids unexpected behavior if defaults change across Saxon versions.
Additionally, reusing the DocumentBuilder and Processor instances aligns with S9API's design—these are heavyweight objects intended to be initialized once and reused for multiple operations, which improves performance.
Is Your Original Code "Wrong"?
Absolutely not! It's a valid, concise way to get the job done. The refactored version just adds robustness, clarity, and adherence to S9API's intended usage patterns, which becomes more valuable as your serialization needs grow (e.g., adding custom output formats, handling different encodings, or validating input documents).
内容的提问来源于stack exchange,提问作者jelovirt

