rdfsaxonxslt-3.0

SAXON XSLT 3.0 unable to generate an xml:base attribute within generated <rdf:RDF /> output


I am using SAXON and an XSL 3.0 transform to generate an RDF file as my target output. Per the W3C RDF specification to properly resolve relative IRIs I need an xml:base URI specified in the generated <rdf:RDF /> header of the file. I'm unable to generated this attribute with the appropriate xml: prefix.

I have the following sample.xml as input to my XSLT 3.0 transform:

<?xml version="1.0" encoding="UTF-8"?>
<Catalog xmlns="http://langdale.com.au/2005/Message#"
         xmlns:m="http://iec.ch/TC57/2013/CPSM-ShortCircuit#"
         ontologyURI="http://iec.ch/TC57/2013/CIM-schema-cim16"
         baseURI="http://iec.ch/TC57/2013/CPSM-ShortCircuit#"
         name="ShortCircuit">
   <Note>This profile represents the equipment of the power system and their hierarchical relationships.</Note>
   <ComplexType name="ACDCTerminal"
                baseClass="http://iec.ch/TC57/2013/CIM-schema-cim16#ACDCTerminal"
                package="Core"
                packageURI="http://iec.ch/TC57/2013/CIM-schema-cim16#Package_Core"
                minOccurs="0"
                maxOccurs="unbounded">
      <Comment>An electrical connection point (AC or DC) to a piece of conducting equipment.</Comment>
      <SuperType name="IdentifiedObject"
                 baseClass="http://iec.ch/TC57/2013/CIM-schema-cim16#IdentifiedObject"/>
   </ComplexType>
   
   <ComplexType name="IdentifiedObject"
                baseClass="http://iec.ch/TC57/2013/CIM-schema-cim16#IdentifiedObject"
                package="Core"
                packageURI="http://iec.ch/TC57/2013/CIM-schema-cim16#Package_Core"
                minOccurs="0"
                maxOccurs="unbounded">
      <Comment>This is a root class to provide common identification for all classes needing identification and naming attributes.</Comment>
      <Simple dataType="http://www.w3.org/2001/XMLSchema#string"
              xstype="string"
              name="mRID"
              baseProperty="http://iec.ch/TC57/2013/CIM-schema-cim16#IdentifiedObject.mRID"
              minOccurs="0"
              maxOccurs="1">
         <Comment>Master resource identifier issued by a model authority.</Comment>
      </Simple>
   </ComplexType>
   
</Catalog>

The XSLT 3.0 transform being applied is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet exclude-result-prefixes="a" version="3.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:cims="http://iec.ch/TC57/1999/rdf-schema-extensions-19990926#" 
    xmlns:a="http://langdale.com.au/2005/Message#" 
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#">

    <xsl:output xmlns:xalan="http://xml.apache.org/xslt" method="xml" omit-xml-declaration="no" indent="yes" xalan:indent-amount="4" />
    <!-- baseURI and ontologyURI parameters passed in. baseURI is for the profile and ontologyURI for the xml:base attribute -->
    <xsl:param name="baseURI"/>
    <xsl:param name="ontologyURI"/>
    <xsl:param name="newline"><xsl:text>
</xsl:text></xsl:param>

    <xsl:template match="a:Catalog">
        <rdf:RDF xml:base="{$ontologyURI}">
            <xsl:variable name="rdf" as="node()*">
                <xsl:apply-templates select=".//*"/>
            </xsl:variable>
            <xsl:perform-sort select="$rdf">
                <xsl:sort select="@rdf:about"/>
            </xsl:perform-sort>
        </rdf:RDF>
    </xsl:template>

<!-- NOTE: remaining template definitions not needed for the example have been removed  -->

</xsl:stylesheet>

Which fails during execution with the below exception when I specify an xml:base attribute as indicated (i.e. <rdf:RDF xml:base="{$ontologyURI}">).

javax.xml.transform.TransformerConfigurationException: net.sf.saxon.s9api.SaxonApiException: I/O error reported by XML parser processing http://langdale.com.au/2005/xsdgen: langdale.com.au
    at net.sf.saxon.jaxp.SaxonTransformerFactory.newTemplates(SaxonTransformerFactory.java:157)
    at au.com.langdale.profiles.ProfileSerializer.addStyleSheet(ProfileSerializer.java:171)
    at au.com.langdale.profiles.ProfileSerializer.setStyleSheet(ProfileSerializer.java:163)
    at au.com.langdale.profiles.ProfileSerializer.setStyleSheet(ProfileSerializer.java:191)
    at au.com.langdale.cimtoole.builder.ProfileBuildlets$TransformBuildlet.build(ProfileBuildlets.java:243)
    at au.com.langdale.cimtoole.builder.ProfileBuildlets$ProfileBuildlet.run(ProfileBuildlets.java:143)
    at au.com.langdale.cimtoole.builder.CIMBuilder$Worker.run(CIMBuilder.java:221)
    at au.com.langdale.cimtoole.builder.CIMBuilder.build(CIMBuilder.java:245)
    at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:728)
    at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
    at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:199)
    at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:239)
    at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:292)
    at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
    at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:295)
    at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:351)
    at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:374)
    at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:143)
    at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:241)
    at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Caused by: net.sf.saxon.s9api.SaxonApiException: I/O error reported by XML parser processing http://langdale.com.au/2005/xsdgen: langdale.com.au
    at net.sf.saxon.s9api.XsltCompiler.compile(XsltCompiler.java:856)
    at net.sf.saxon.jaxp.SaxonTransformerFactory.newTemplates(SaxonTransformerFactory.java:154)
    ... 19 more
Caused by: net.sf.saxon.trans.XPathException: I/O error reported by XML parser processing http://langdale.com.au/2005/xsdgen: langdale.com.au
    at net.sf.saxon.event.Sender.sendSAXSource(Sender.java:467)
    at net.sf.saxon.event.Sender.send(Sender.java:168)
    at net.sf.saxon.style.StylesheetModule.sendStylesheetSource(StylesheetModule.java:157)
    at net.sf.saxon.style.StylesheetModule.loadStylesheet(StylesheetModule.java:229)
    at net.sf.saxon.style.Compilation.compileSingletonPackage(Compilation.java:113)
    at net.sf.saxon.s9api.XsltCompiler.compile(XsltCompiler.java:851)
    ... 20 more
Caused by: java.net.UnknownHostException: langdale.com.au
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:184)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:613)
    at java.net.Socket.connect(Socket.java:561)
    at sun.net.NetworkClient.doConnect(NetworkClient.java:180)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:463)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:558)
    at sun.net.www.http.HttpClient.<init>(HttpClient.java:242)
    at sun.net.www.http.HttpClient.New(HttpClient.java:339)
    at sun.net.www.http.HttpClient.New(HttpClient.java:357)
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1233)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1167)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1061)
    at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:995)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1577)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1505)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:648)
    at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:148)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:805)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:770)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:642)
    at net.sf.saxon.event.Sender.sendSAXSource(Sender.java:439)
    ... 25 more
---------
net.sf.saxon.s9api.SaxonApiException: I/O error reported by XML parser processing http://langdale.com.au/2005/xsdgen: langdale.com.au
    at net.sf.saxon.s9api.XsltCompiler.compile(XsltCompiler.java:856)
    at net.sf.saxon.jaxp.SaxonTransformerFactory.newTemplates(SaxonTransformerFactory.java:154)
    at au.com.langdale.profiles.ProfileSerializer.addStyleSheet(ProfileSerializer.java:171)
    at au.com.langdale.profiles.ProfileSerializer.setStyleSheet(ProfileSerializer.java:163)
    at au.com.langdale.profiles.ProfileSerializer.setStyleSheet(ProfileSerializer.java:191)
    at au.com.langdale.cimtoole.builder.ProfileBuildlets$TransformBuildlet.build(ProfileBuildlets.java:243)
    at au.com.langdale.cimtoole.builder.ProfileBuildlets$ProfileBuildlet.run(ProfileBuildlets.java:143)
    at au.com.langdale.cimtoole.builder.CIMBuilder$Worker.run(CIMBuilder.java:221)
    at au.com.langdale.cimtoole.builder.CIMBuilder.build(CIMBuilder.java:245)
    at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:728)
    at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
    at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:199)
    at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:239)
    at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:292)
    at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
    at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:295)
    at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:351)
    at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:374)
    at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:143)
    at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:241)
    at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Caused by: net.sf.saxon.trans.XPathException: I/O error reported by XML parser processing http://langdale.com.au/2005/xsdgen: langdale.com.au
    at net.sf.saxon.event.Sender.sendSAXSource(Sender.java:467)
    at net.sf.saxon.event.Sender.send(Sender.java:168)
    at net.sf.saxon.style.StylesheetModule.sendStylesheetSource(StylesheetModule.java:157)
    at net.sf.saxon.style.StylesheetModule.loadStylesheet(StylesheetModule.java:229)
    at net.sf.saxon.style.Compilation.compileSingletonPackage(Compilation.java:113)
    at net.sf.saxon.s9api.XsltCompiler.compile(XsltCompiler.java:851)
    ... 20 more
Caused by: java.net.UnknownHostException: langdale.com.au
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:184)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:613)
    at java.net.Socket.connect(Socket.java:561)
    at sun.net.NetworkClient.doConnect(NetworkClient.java:180)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:463)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:558)
    at sun.net.www.http.HttpClient.<init>(HttpClient.java:242)
    at sun.net.www.http.HttpClient.New(HttpClient.java:339)
    at sun.net.www.http.HttpClient.New(HttpClient.java:357)
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1233)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1167)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1061)
    at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:995)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1577)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1505)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:648)
    at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:148)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:805)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:770)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:642)
    at net.sf.saxon.event.Sender.sendSAXSource(Sender.java:439)
    ... 25 more

If I hardcode the value instead it generates successfully (i.e. hardcoded as <rdf:RDF xml:base="http://iec.ch/TC57/2013/CIM-schema-cim16">) but I need to be able to programmaticaly pass in different base URIs.

When I leave the expression in place and remove the xml: prefix (i.e. <rdf:RDF base="{$ontologyURI}">) the XSLT then works with the RDF header output as shown below. However, per the W3C RDF spec I need the fully prefixed attribute (xml:base) for the baseURI for resolving relative IRIs.

<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF 
    xmlns:cims="http://iec.ch/TC57/1999/rdf-schema-extensions-19990926#" 
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
    base="http://iec.ch/TC57/2013/CIM-schema-cim16">
    
...
...
    
</rdf:RDF>

Solution

  • The use of xml:base in the stylesheet is being interpreted as a base attribute on the element on which it occurs. Like xml:id using it as a literal attribute places it's semantics on the element in the stylesheet.

    You can avoid this with:

    <rdf:RDF>
      <xsl:attribute name="xml:base" select="$ontologyURI"/>
      ...