Module xrust::xslt

source ·
Expand description

An XSLT compiler

Compile an XSLT stylesheet into a Transformation.

Once the stylesheet has been compiled, it may then be evaluated with an appropriate context.

NB. This module, by default, does not resolve include or import statements. See the xrust-net crate for a helper module to do that.

use std::rc::Rc;
use xrust::xdmerror::Error;
use xrust::qname::QualifiedName;
use xrust::item::{Item, Node, NodeType, Sequence, SequenceTrait};
use xrust::transform::Transform;
use xrust::transform::context::StaticContext;
use xrust::trees::intmuttree::{Document, RNode, NodeBuilder};
use xrust::xslt::from_document;

// This is for the callback in the static context
type F = Box<dyn FnMut(&str) -> Result<(), Error>>;

// A little helper function that wraps the toplevel node in a Document
fn make_from_str(s: &str) -> Result<RNode, Error> {
    let e = Document::try_from((s, None, None)).expect("failed to parse XML").content[0].clone();
    let mut d = NodeBuilder::new(NodeType::Document).build();
    d.push(e).expect("unable to append node");
    Ok(d)
}

// The source document (a tree)
let src = Rc::new(Item::Node(
    make_from_str("<Example><Title>XSLT in Rust</Title><Paragraph>A simple document.</Paragraph></Example>")
    .expect("unable to parse XML")
));

// The XSL stylesheet
let style = make_from_str("<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
  <xsl:template match='child::Example'><html><xsl:apply-templates/></html></xsl:template>
  <xsl:template match='child::Title'><head><title><xsl:apply-templates/></title></head></xsl:template>
  <xsl:template match='child::Paragraph'><body><p><xsl:apply-templates/></p></body></xsl:template>
</xsl:stylesheet>")
    .expect("unable to parse stylesheet");

// Compile the stylesheet
let mut ctxt = from_document(
    style,
    None,
    make_from_str,
    |_| Ok(String::new())
).expect("failed to compile stylesheet");

// Set the source document as the context item
ctxt.context(vec![src], 0);
// Make an empty result document
ctxt.result_document(NodeBuilder::new(NodeType::Document).build());

// Let 'er rip!
// Evaluate the transformation
let seq = ctxt.evaluate(&mut StaticContext::<F>::new())
    .expect("evaluation failed");

// Serialise the sequence as XML
assert_eq!(seq.to_xml(), "<html><head><title>XSLT in Rust</title></head><body><p>A simple document.</p></body></html>")

Traits

  • The XSLT trait allows an object to use an XSL Stylesheet to transform a document into a Sequence.

Functions

  • Compiles a Node into a transformation Context. NB. Due to whitespace stripping, this is destructive of the stylesheet. The argument f is a closure that parses a string to a Node. The argument g is a closure that resolves a URL to a string. These are used for include and import modules. They are not included in this module since some environments, in particular Wasm, do not have I/O facilities.
  • Strip whitespace nodes from a XDM tree. This function operates under the direction of the xsl:strip-space and xsl:preserve-space directives in a XSLT stylesheet.
  • Strip whitespace nodes from a XDM tree. See XSLT 4.3. The Node argument must be the document node of the tree.