Skip to content

Commit

Permalink
Stylesheet base URI working
Browse files Browse the repository at this point in the history
Test runner passing document URI where that exists, and we set it up as the system id to the Saxon transformer if it does exist.

Debugging verbosity tidied up, along with some early dev code; we want to get as many XQTS tests to run as we can and resolve any missing code in TDD-style from the failing XQTS.
  • Loading branch information
alanpaxton committed Jun 9, 2022
1 parent 2b1291b commit 1a96d0e
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 23 deletions.
Expand Up @@ -68,6 +68,7 @@
import java.io.StringReader;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;

import static com.evolvedbinary.j8fu.tuple.Tuple.Tuple;
Expand Down Expand Up @@ -158,6 +159,7 @@ public Sequence eval(final Sequence[] args, final Sequence contextSequence) thro
} else {
stylesheetBaseUri = xsltSource._1;
}
final AnyURIValue resolvedStylesheetBaseURI = resolveURI(new AnyURIValue(stylesheetBaseUri), context.getBaseURI());

final Optional<QNameValue> initialTemplate = FnTransform.INITIAL_TEMPLATE.get(options);

Expand All @@ -181,7 +183,11 @@ public Sequence eval(final Sequence[] args, final Sequence contextSequence) thro
}

try {
xsltSource._2.setSystemId(context.getBaseURI().getStringValue());
if (!resolvedStylesheetBaseURI.isEmpty()) {
xsltSource._2.setSystemId(resolvedStylesheetBaseURI.getStringValue());
} else {
xsltSource._2.setSystemId(context.getBaseURI().getStringValue());
}
return xsltCompiler.compile(xsltSource._2); // .compilePackage //TODO(AR) need to implement support for xslt-packages
} catch (final SaxonApiException e) {
compileException.value = e;
Expand All @@ -198,25 +204,10 @@ public Sequence eval(final Sequence[] args, final Sequence contextSequence) thro

final Xslt30Transformer xslt30Transformer = xsltExecutable.load30();

// XdmValue xdmValue; //= xslt30Transformer.applyTemplates();
// Serializer serializer = processor.newSerializer();
//processor.newDocumentBuilder().newBuildingContentHandler()

// //TODO temp
// final StringWriter writer = new StringWriter();
// final Serializer serializer = SAXON_PROCESSOR.newSerializer(writer);
// xslt30Transformer.applyTemplates(sourceNode, serializer);
// return null;
// //TODO end temp

// TODO(AR) this is just for DOM results... need to handle other response types!
final MemTreeBuilder builder = context.getDocumentBuilder();
final DocumentBuilderReceiver builderReceiver = new DocumentBuilderReceiver(builder);

//TODO(AP) might need to set the base output URI to pass some tests ? See specification
//final AnyURIValue baseURI = context.getBaseURI();
//xslt30Transformer.setBaseOutputURI(baseURI.getStringValue());

// Record the secondary result documents generated
final Map<URI, MemTreeBuilder> resultDocuments = new HashMap<>();
xslt30Transformer.setResultDocumentHandler(resultDocumentURI -> {
Expand All @@ -225,7 +216,6 @@ public Sequence eval(final Sequence[] args, final Sequence contextSequence) thro
resultDocuments.put(resultDocumentURI, resultBuilder);
return new SAXDestination(resultBuilderReceiver);
});
System.err.println("resultURI: [" + resultDocuments.size() + "]");

final SAXDestination saxDestination = new SAXDestination(builderReceiver);
if (initialTemplate.isPresent()) {
Expand All @@ -246,10 +236,6 @@ public Sequence eval(final Sequence[] args, final Sequence contextSequence) thro
}
xslt30Transformer.applyTemplates(sourceNode.get(), saxDestination);
}
System.err.println("resultDocuments:");
for (final URI resultURI : resultDocuments.keySet()) {
System.err.println("resultURI: " + resultURI);
}
return makeResultMap(xsltVersion, options, builder.getDocument(), resultDocuments);

} catch (final SaxonApiException e) {
Expand Down Expand Up @@ -363,6 +349,30 @@ private Source resolveStylesheetLocation(final String stylesheetLocation) throws
}
}

/**
* URI resolution, the core should be the same as for fn:resolve-uri
* @param relative
* @param base
* @return
* @throws XPathException
*/
private AnyURIValue resolveURI(final AnyURIValue relative, final AnyURIValue base) throws XPathException {
final URI relativeURI;
final URI baseURI;
try {
relativeURI = new URI(relative.getStringValue());
baseURI = new URI(base.getStringValue() );
} catch (final URISyntaxException e) {
throw new XPathException(this, ErrorCodes.FORG0009, "unable to resolve a relative URI against a base URI in fn:transform(): " + e.getMessage(), null, e);
}
if (relativeURI.isAbsolute()) {
return relative;
} else {
return new AnyURIValue(baseURI.resolve(relativeURI));
}

}

/**
* Get the stylesheet.
*
Expand All @@ -377,7 +387,8 @@ private Tuple2<String, Source> getStylesheet(final MapType options) throws XPath

final Optional<Node> stylesheetNode = FnTransform.STYLESHEET_NODE.get(options).map(NodeValue::getNode);
if (stylesheetNode.isPresent()) {
return Tuple(stylesheetNode.get().getBaseURI(), new DOMSource(stylesheetNode.get()));
final Node node = stylesheetNode.get();
return Tuple(node.getBaseURI(), new DOMSource(node));
}

final Optional<String> stylesheetText = FnTransform.STYLESHEET_TEXT.get(options).map(StringValue::getStringValue);
Expand Down
2 changes: 1 addition & 1 deletion exist-core/src/test/java/xquery/xquery3/XQuery3Tests.java
Expand Up @@ -27,7 +27,7 @@
@RunWith(XSuite.class)
@XSuite.XSuiteFiles({
//"src/test/xquery/xquery3",
"src/test/xquery/xquery3/fnTransform7c.xqm"
"src/test/xquery/xquery3/fnTransform39.xqm"
})
public class XQuery3Tests {
}
69 changes: 69 additions & 0 deletions exist-core/src/test/xquery/xquery3/fnTransform39.xqm
@@ -0,0 +1,69 @@
(:
: eXist-db Open Source Native XML Database
: Copyright (C) 2001 The eXist-db Authors
:
: info@exist-db.org
: http://www.exist-db.org
:
: This library is free software; you can redistribute it and/or
: modify it under the terms of the GNU Lesser General Public
: License as published by the Free Software Foundation; either
: version 2.1 of the License, or (at your option) any later version.
:
: This library is distributed in the hope that it will be useful,
: but WITHOUT ANY WARRANTY; without even the implied warranty of
: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
: Lesser General Public License for more details.
:
: You should have received a copy of the GNU Lesser General Public
: License along with this library; if not, write to the Free Software
: Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
:)
xquery version "3.1";

module namespace testTransform="http://exist-db.org/xquery/test/function_transform";

declare namespace test="http://exist-db.org/xquery/xqsuite";

declare variable $testTransform:transform-39-multiple-docs-2-xsl := document { <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
<xsl:template match="/">
<xsl:for-each select="//section">
<xsl:result-document method="xhtml" href="{resolve-uri(concat('sandbox/fn-transform-39/section', position(),'.html'), "file://Users/alan/txx")}">
<html>
<head>
<title>Section <xsl:value-of select="position()"/></title>
</head>
<body>
<h1>Header for section <xsl:value-of select="position()"/></h1>
<p>The content of <xsl:value-of select="."/>.</p>
<xsl:if test="position() ne last()">
<p><a href="section{position()+1}.html">Next section</a></p>
</xsl:if>
<xsl:if test="position() eq last()">
<p><a href="section1.html">First section</a></p>
</xsl:if>
</body>
</html>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet> };

declare variable $testTransform:transform-39-doc-sections := document { <doc>
<section>sect1</section>
<section>sect2</section>
<section>sect3</section>
</doc>
};

declare
%test:assertTrue
function testTransform:transform-39() {
let $style := $testTransform:transform-39-multiple-docs-2-xsl
let $sections := $testTransform:transform-39-doc-sections
let $result := fn:transform(map {"stylesheet-node":$style, "source-node":$sections,
"delivery-format":"serialized"})
return contains(string-join($result), 'section1.html')
};

0 comments on commit 1a96d0e

Please sign in to comment.