Re: How to get xsl:output/@method after transformation?
John Ulric <[email protected]> Sun, 2 May 2021 23:01:08 +0200
| Newsgroups | gmane.text.xml.saxon.help |
|---|---|
| Message-ID | <CANS5Rie=U+itibXRouaEOSoe-O_x2E=uYfic-FDZbLcQCLN6Ww@mail.gmail.com> |
Michael, thank you so much for looking into this. Works like you said.
For the record, below I've attached the code of how I've now packaged this.
This is somewhat, well … obscure. ;-) No offence intended. And I see no
easy way to avoid the ungainly ThreadLocal, except
wrapping/overriding/delegating the whole chain of
.newXsltCompiler()/XsltCompiler/.compile()/XsltExecutable/.load()/… up
until the Destination.
Would you consider adding a more official API for this? Should I file an
issue?
John
static class ProcessorCapturingOutputParams extends Processor {
ProcessorCapturingOutputParams(final Configuration config) {
super(withCapturing(config));
}
static Configuration withCapturing(Configuration configuration) {
configuration.setSerializerFactory(new
SerializerFactoryCapturingOutputParams(configuration)); // todo: to be
safe, chain this with any existing serializer factory?
return configuration;
}
public String getActualOutputMethod() {
return lastProperties().map(p -> p.getProperty("method")).orElse(null);
}
public void clear() {
((SerializerFactoryCapturingOutputParams)
getUnderlyingConfiguration().getSerializerFactory()).lastProperties.remove();
}
private Optional<Properties> lastProperties() {
return Optional.ofNullable(((SerializerFactoryCapturingOutputParams)
getUnderlyingConfiguration().getSerializerFactory()).lastProperties.get());
}
private static class SerializerFactoryCapturingOutputParams
extends SerializerFactory {
private final ThreadLocal<Properties> lastProperties = new
ThreadLocal<>();
private SerializerFactoryCapturingOutputParams(final
Configuration config) {
super(config);
}
@Override
public Receiver getReceiver(final Result result, final
SerializationProperties params, final PipelineConfiguration pipe)
throws XPathException {
lastProperties.set(ofNullable(params.getProperties()).map(Properties::new).orElse(null));
return super.getReceiver(result, params, pipe);
}
}
}
Am Sa., 1. Mai 2021 um 17:12 Uhr schrieb Michael Kay <mike-JkSD5nQpfvpWk0Htik3J/[email protected]>:
> Yes, I've looked at this in more detail, and it seems that when the
> decision between XML/XHTML/HTML serialization is delayed until the first
> element tag is output, the only way you can intercept this is by
> subclassing the SerializerFactory and nominating your subclass using
> Configuration.setSerializerFactory(). If you override the method
>
> public Receiver getReceiver(Result result,
> SerializationProperties params,
> PipelineConfiguration pipe)
>
> the first call will be with params that don't include a method. This call
> will therefore allocate an UncommittedSerializer. When the
> UncommittedSerializer gets a startElement() event it calls the
> SerializerFactory a second time, and on this occasion the params will
> include the selected method.
>
> Michael Kay
> Saxonica
>
>
_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
[email protected]
https://lists.sourceforge.net/lists/listinfo/saxon-help