Using nilled in XPath

Even though it was introduced in 2007, it ain’t supported by Apache Xalan yet, but only by Saxon-SA.

Document.xml

<?xml version="1.0" encoding="UTF-8"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Schema.xsd">
  <Element xsi:nil="true"/>
</Root>

Schema.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Element" nillable="true">
          <xs:complexType/>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Stylesheet.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/Root">
    <Root>
      <Element>
        <xsl:choose>
          <xsl:when test="nilled(Element)">0</xsl:when>
          <xsl:otherwise>1</xsl:otherwise>
        </xsl:choose>
      </Element>
    </Root>
  </xsl:template>
</xsl:stylesheet>

SaxonSample.java

import java.io.FileReader;

import net.sf.saxon.FeatureKeys;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.xml.sax.InputSource;

import static java.lang.System.out;

public final class SaxonSASample2 {

  public static void main(final String[] args) throws Exception {
    final TransformerFactory factory = TransformerFactory.newInstance(); // ensure javax.xml.transform.TransformerFactory system property is set to com.saxonica.SchemaAwareTransformerFactory

    factory.setAttribute(FeatureKeys.SCHEMA_VALIDATION_MODE, "strict");

    final Transformer transformer = factory.newTransformer(new StreamSource(new FileReader("Stylesheet.xsl")));

    transformer.transform(new SAXSource(new InputSource(new FileReader("Document.xml"))), new StreamResult(out));
  }

}

It doesn’t work with a DOM source because the type annotations of all elements is stripped to xs:untyped by Saxon-SA, whether they have been validated or not.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s