Having trouble getting a document node back from extension function.
authorTony Graham
Sun, 15 Dec 2013 21:54:25 +0000
changeset 20 8692c49d26d3
parent 19 d7ac27d3c5a4
child 21 4de832b72c0d
Having trouble getting a document node back from extension function.
FOPRunXSLTExt/examples/example5_saxon9_ahf61.xsl
FOPRunXSLTExt/src/org/w3c/ppl/xslt/ext/ahf/saxon/RunAHFSaxon.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FOPRunXSLTExt/examples/example5_saxon9_ahf61.xsl	Sun Dec 15 21:54:25 2013 +0000
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ============================================================= -->
+<!-- FOPRunXSLTExt Saxon example 5                                 -->
+<!--                                                               -->
+<!-- See http://www.w3.org/community/ppl/wiki/FOPRunXSLTExt        -->
+<!--                                                               -->
+<!-- Requires Saxon 9.4 or later and FOP 1.0                       -->
+<!--                                                               -->
+<!-- Produced by the Print and Page Layout Community Group @ W3C   -->
+<!-- ============================================================= -->
+<xsl:stylesheet
+    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    version="2.0"
+    xmlns:fo="http://www.w3.org/1999/XSL/Format"
+    xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    xmlns:runahf="http://org.w3c.ppl.xslt/saxon-extension"
+    exclude-result-prefixes="xs runahf">
+
+<!-- Common templates for formatting FOPRunXSLTExt examples -->
+<xsl:import href="formatting.xsl" />
+
+<xsl:key name="boxes" match="box" use="true()" />
+
+<xsl:key name="blocks" match="block[exists(@prod-id)]" use="@prod-id" />
+
+<xsl:param name="font-size" select="12" as="xs:double" />
+
+<!-- Where to write the output files. -->
+<xsl:param name="dest_dir" select="out" as="xs:string"/>
+<xsl:param name="tolerance" select="1" as="xs:double" />
+
+<!-- Initial template -->
+<xsl:template name="main">
+  <xsl:call-template name="do-box">
+    <xsl:with-param name="font-size" select="$font-size" as="xs:double" />
+    <xsl:with-param
+        name="font-size.minimum" select="$font-size" as="xs:double" tunnel="yes" />
+    <xsl:with-param
+        name="font-size.maximum" select="$font-size * 10" as="xs:double" tunnel="yes" />
+    <xsl:with-param name="iteration" select="1" as="xs:integer" />
+    <xsl:with-param name="iteration-max" select="30" as="xs:integer" tunnel="yes" />
+    <xsl:with-param name="tolerance" select="$tolerance" as="xs:double" tunnel="yes" />
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="do-box">
+  <xsl:param name="font-size" as="xs:double" />
+  <xsl:param name="font-size.minimum" as="xs:double" tunnel="yes" />
+  <xsl:param name="font-size.maximum" as="xs:double" tunnel="yes" />
+  <xsl:param name="iteration" select="1" as="xs:integer" />
+  <xsl:param name="iteration-max" select="5" as="xs:integer" tunnel="yes" />
+  <xsl:param name="tolerance" select="$tolerance" as="xs:double" tunnel="yes" />
+
+  <xsl:message>iteration = <xsl:value-of select="$iteration" /></xsl:message>
+  <xsl:message>font-size = <xsl:value-of select="$font-size" /></xsl:message>
+  <xsl:message>font-size.minimum = <xsl:value-of select="$font-size.minimum" /></xsl:message>
+  <xsl:message>font-size.maximum = <xsl:value-of select="$font-size.maximum" /></xsl:message>
+
+  <xsl:variable name="overrides">
+    <overrides>
+      <!-- Set the font size. -->
+      <xsl:for-each select="key('boxes', true())">
+	<xsl:variable name="id" select="@id" as="xs:string" />
+	<override id="{$id}" font-size="{$font-size}" />
+      </xsl:for-each>
+    </overrides>
+  </xsl:variable>
+
+  <!-- Save the FO tree in a variable. -->
+  <xsl:variable name="fo_tree">
+    <xsl:apply-templates select="/">
+      <xsl:with-param name="overrides" select="$overrides" as="document-node()" tunnel="yes" />
+    </xsl:apply-templates>
+  </xsl:variable>
+
+  <xsl:variable
+      name="area-tree"
+      select="runahf:area-tree($fo_tree)"
+      as="document-node()?" />
+
+  <xsl:variable
+      name="bpd"
+      select="key('blocks', key('boxes', true())[1]/@id, $area-tree)[1]/block/@bpd"
+      as="xs:integer" />
+
+  <xsl:variable
+      name="target-height"
+      select="xs:double(substring-before(key('boxes', true())[1]/@height, 'pt'))"
+      as="xs:double" />
+
+  <xsl:choose>
+    <xsl:when test="$iteration eq $iteration-max">
+      <xsl:message>Maximum iterations.</xsl:message>
+      <xsl:apply-templates select="/">
+        <xsl:with-param
+            name="overrides"
+            select="$overrides"
+            as="document-node()"
+            tunnel="yes" />
+      </xsl:apply-templates>
+    </xsl:when>
+    <xsl:when test="$bpd div 1000 > $target-height">
+      <xsl:call-template name="do-box">
+        <xsl:with-param
+            name="font-size"
+            select="($font-size + $font-size.minimum) div 2"
+            as="xs:double" />
+        <xsl:with-param
+            name="font-size.maximum"
+            select="$font-size"
+            as="xs:double"
+            tunnel="yes" />
+        <xsl:with-param name="iteration" select="$iteration + 1" as="xs:integer" />
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="$target-height - ($bpd div 1000) &lt;
+                    $target-height * $tolerance div $target-height">
+      <xsl:message>It fits.</xsl:message>
+      <xsl:apply-templates select="/">
+        <xsl:with-param
+            name="overrides"
+            select="$overrides"
+            as="document-node()"
+            tunnel="yes" />
+      </xsl:apply-templates>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="do-box">
+        <xsl:with-param
+            name="font-size"
+            select="($font-size + $font-size.maximum) div 2"
+            as="xs:double" />
+        <xsl:with-param
+            name="font-size.mimimum"
+            select="$font-size"
+            as="xs:double"
+            tunnel="yes" />
+        <xsl:with-param name="iteration" select="$iteration + 1" as="xs:integer" />
+      </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
--- a/FOPRunXSLTExt/src/org/w3c/ppl/xslt/ext/ahf/saxon/RunAHFSaxon.java	Mon Dec 02 15:45:28 2013 +0000
+++ b/FOPRunXSLTExt/src/org/w3c/ppl/xslt/ext/ahf/saxon/RunAHFSaxon.java	Sun Dec 15 21:54:25 2013 +0000
@@ -6,13 +6,15 @@
 import net.sf.saxon.lib.ExtensionFunctionCall;
 import net.sf.saxon.lib.ExtensionFunctionDefinition;
 import net.sf.saxon.om.Item;
+import net.sf.saxon.om.Sequence;
 import net.sf.saxon.om.SequenceIterator;
 import net.sf.saxon.om.StructuredQName;
 import net.sf.saxon.trans.XPathException;
 import net.sf.saxon.tree.tiny.TinyDocumentImpl;
+import net.sf.saxon.value.AtomicValue;
 import net.sf.saxon.value.SequenceType;
+import net.sf.saxon.value.SingletonItem;
 import net.sf.saxon.value.StringValue;
-import net.sf.saxon.value.Value;
 import net.sf.saxon.value.ObjectValue;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
@@ -59,10 +61,9 @@
     public ExtensionFunctionCall makeCallExpression() {
         return new ExtensionFunctionCall() {
             @Override
-            public SequenceIterator<? extends Item> call(SequenceIterator<? extends Item>[] sis,
-                    XPathContext xpc) throws XPathException {
+            public Sequence call(XPathContext context, Sequence[] arguments) throws XPathException {
                 
-                TinyDocumentImpl item = (TinyDocumentImpl) sis[0].next();
+                TinyDocumentImpl item = (TinyDocumentImpl) arguments[0].head();
                 Document foTree = (Document) DocumentOverNodeInfo.wrap(item);
                 ByteArrayInputStream isFo = null;
                 ByteArrayOutputStream osAt = null;
@@ -75,9 +76,12 @@
                     ErrDump eDump = new ErrDump();
                     axfo.setMessageListener(eDump);
                     axfo.setExitLevel(4);
+                    axfo.setPrinterName("@AreaTree");
                     axfo.render(isFo, osAt, "@AreaTree");
                     StreamSource sAt = new StreamSource(new ByteArrayInputStream(osAt.toByteArray()));
-                    return Value.asIterator(new ObjectValue(sAt));
+                    //return new ObjectValue(context.getConfiguration().buildDocument(sAt));
+                    //return new ObjectValue(sAt);
+                    return new ObjectValue(DocumentOverNodeInfo.wrap(context.getConfiguration().buildDocument(sAt)));
                 } catch (Exception ex) {
                     ex.printStackTrace();
                     throw new XPathException(ex);