How Does unparsed-text() Load Non-XML into XSLT 2.0?

The unparsed-text() function in XSLT 2.0 allows stylesheets to read external non-XML text files directly into transformations as raw string data. Prior to XSLT 2.0, processors could natively load only well-formed XML documents via functions like document() or doc(). By introducing unparsed-text(), XSLT 2.0 provides native support for ingesting plain text formats—such as CSV, TSV, JSON, log files, or legacy delimited data—and converting them into structured XML without requiring external pre-processing tools or proprietary extensions.

Core Purpose and Mechanics

The primary role of unparsed-text() is to retrieve a resource identified by a Uniform Resource Identifier (URI) and return its contents as a single xs:string. Unlike the doc() function, which parses the target resource with an XML parser and produces a document node, unparsed-text() treats the target strictly as a sequence of characters.

The function signature supports up to two arguments:

unparsed-text($href as xs:string?) as xs:string?
unparsed-text($href as xs:string?, $encoding as xs:string) as xs:string?

Processing Non-XML Content in XSLT 2.0

Once non-XML content is loaded as a string via unparsed-text(), it is typically parsed into XML elements using XSLT 2.0's string-manipulation and regular-expression features.

Key complementary functions and instructions include:

Example: Converting CSV to XML

Below is a practical example showing how unparsed-text() loads a comma-separated values file and transforms it into XML nodes:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template name="main">
    <root>
      <xsl:if test="unparsed-text-available('data.csv', 'UTF-8')">
        <xsl:variable name="raw-text" select="unparsed-text('data.csv', 'UTF-8')"/>
        <xsl:for-each select="tokenize($raw-text, '\r?\n')[normalize-space()]">
          <row>
            <xsl:for-each select="tokenize(., ',')">
              <cell><xsl:value-of select="normalize-space(.)"/></cell>
            </xsl:for-each>
          </row>
        </xsl:for-each>
      </xsl:if>
    </root>
  </xsl:template>
</xsl:stylesheet>

Benefits in Modern Pipelines

Using unparsed-text() provides several distinct advantages in data integration pipelines:

  1. Pipeline Simplification: Eliminates the need for external scripts (such as Python or Bash wrappers) to convert text files into XML before running transformations.
  2. Hybrid Processing: Enables single-pass transformations that combine XML datasets with external lookup tables stored in flat files.
  3. Deterministic Encodings: Allows explicit control over character encodings, reducing character corruption across legacy text formats.