net.sf.saxon.functions.Serialize Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of saxon9 Show documentation
Show all versions of saxon9 Show documentation
Provides a basic XSLT 2.0 and XQuery 1.0 processor (W3C Recommendations,
January 2007). Command line interfaces and implementations of several
Java APIs (DOM, XPath, s9api) are also included.
The newest version!
package net.sf.saxon.functions;
import net.sf.saxon.event.SequenceReceiver;
import net.sf.saxon.expr.ExpressionVisitor;
import net.sf.saxon.expr.StaticContext;
import net.sf.saxon.expr.StringLiteral;
import net.sf.saxon.expr.XPathContext;
import net.sf.saxon.instruct.ResultDocument;
import net.sf.saxon.om.*;
import net.sf.saxon.style.ExpressionContext;
import net.sf.saxon.trace.Location;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.type.Type;
import net.sf.saxon.value.StringValue;
import net.sf.saxon.value.Whitespace;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;
import java.util.Properties;
/**
* This class implements the saxon:serialize() extension function,
* which is specially-recognized by the system because it needs access
* to parts of the static context
*/
public class Serialize extends SystemFunction implements XSLTFunction {
Properties outputProperties;
private transient boolean checked = false;
// the second time checkArguments is called, it's a global check so the static context is inaccurate
/**
* Method supplied by each class of function to check arguments during parsing, when all
* the argument expressions have been read
*/
public void checkArguments(ExpressionVisitor visitor) throws XPathException {
if (checked) return;
checked = true;
super.checkArguments(visitor);
if (argument[1] instanceof StringLiteral) {
StaticContext env = visitor.getStaticContext();
if (env instanceof ExpressionContext) {
// We're in XSLT
String formatString = ((StringLiteral)argument[1]).getStringValue();
StructuredQName formatQName = null;
if (formatString.length() != 0) {
formatQName = ((ExpressionContext)env).getStructuredQName(formatString, false);
// if (fingerprint==-1) {
// throw new XPathException("Output format '" + format + "' has not been defined");
// }
}
outputProperties = ((ExpressionContext)env).getXSLStylesheet().gatherOutputProperties(formatQName);
} else {
// we're not in XSLT: treat the second argument as the method property, default the rest
// See https://sourceforge.net/forum/message.php?msg_id=3780729
outputProperties = new Properties();
outputProperties.setProperty(OutputKeys.METHOD, ((StringLiteral)argument[1]).getStringValue());
}
}
}
/**
* Evaluate the function
*/
public Item evaluateItem(XPathContext c) throws XPathException {
NodeInfo node = (NodeInfo)argument[0].evaluateItem(c);
if (node==null) {
return StringValue.EMPTY_STRING;
}
Properties props = outputProperties;
if (props == null) {
// the second argument was not a literal string: in this case it must be an xsl:output element
Item secondArg = argument[1].evaluateItem(c);
if (!(secondArg instanceof NodeInfo &&
((NodeInfo)secondArg).getNodeKind() == Type.ELEMENT &&
((NodeInfo)secondArg).getFingerprint() == StandardNames.XSL_OUTPUT)) {
XPathException err = new XPathException("The second argument of saxon:serialize must either be " +
"a string literal, or an xsl:output element");
err.setXPathContext(c);
throw err;
}
props = new Properties();
processXslOutputElement((NodeInfo)secondArg, props, c);
}
try {
StringWriter result = new StringWriter();
XPathContext c2 = c.newMinorContext();
c.setOriginatingConstructType(Location.SAXON_SERIALIZE);
c2.changeOutputDestination(props,
new StreamResult(result),
false,
getHostLanguage(),
Validation.PRESERVE,
null);
SequenceReceiver out = c2.getReceiver();
out.open();
node.copy(out, NodeInfo.ALL_NAMESPACES, true, locationId);
out.close();
return new StringValue(result.toString());
} catch (XPathException err) {
throw new XPathException(err);
}
}
/**
* Construct a set of output properties from an xsl:output element supplied at run-time
* @param element an xsl:output element
* @param props Properties object to which will be added the values of those serialization properties
* that were specified
* @param c the XPath dynamic context
*/
public static void processXslOutputElement(NodeInfo element, Properties props, XPathContext c) throws XPathException {
SequenceIterator iter = element.iterateAxis(Axis.ATTRIBUTE);
NameChecker nc = c.getConfiguration().getNameChecker();
NamespaceResolver resolver = new InscopeNamespaceResolver(element);
while (true) {
NodeInfo att = (NodeInfo)iter.next();
if (att == null) {
break;
}
String uri = att.getURI();
String local = att.getLocalPart();
String val = Whitespace.trim(att.getStringValueCS());
ResultDocument.setSerializationProperty(props, uri, local, val, resolver, false, nc);
}
}
}
//
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
// you may not use this file except in compliance with the License. You may obtain a copy of the
// License at http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
// See the License for the specific language governing rights and limitations under the License.
//
// The Original Code is: all this file.
//
// The Initial Developer of the Original Code is Michael H. Kay.
//
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
//
// Contributor(s): none.
//
© 2015 - 2025 Weber Informatics LLC | Privacy Policy